インデックスのプリフェッチの概要

AlloyDB for PostgreSQL は、インデックス プリフェッチを使用して、B ツリー インデックスを介して一連の行を読み取るクエリを高速化します。インデックス プリフェッチは、PostgreSQL 17 以降を実行する AlloyDB インスタンスと AlloyDB Omni インスタンスでデフォルトで有効になっています。この機能を利用するために、フラグの設定、インデックスの再構築、アプリケーションや SQL クエリの変更を行う必要はありません。

インデックスのプリフェッチの仕組み

クエリがインデックスを介して値の範囲をスキャンする場合(インデックス付き列の BETWEEN 述語や ORDER BY ... LIMIT 句など)、スキャンはインデックス ページと、インデックス エントリが指すテーブルページを読み取ります。これらのテーブルページは、多くの場合、ストレージ全体に分散しています。標準の PostgreSQL では、スキャンはこれらのページを 1 つずつ読み取るため、ページがメモリにまだ存在しない場合、クエリはほとんどの時間をストレージ I/O の待機に費やします。

インデックス プリフェッチを使用すると、AlloyDB はインデックスとテーブルの両方で実行中のスキャンを先読みし、スキャンが必要とするページを並行して読み取ります。AlloyDB は、プリフェッチされたページをインスタンスのローカル SSD キャッシュにステージングします。これにより、スキャンがページをリクエストすると、ページはリモート ストレージではなく高速なローカル ストレージから提供されます。プリフェッチされたページは PostgreSQL 共有バッファの外部にステージングされるため、プリフェッチによって他のセッションで使用可能なバッファ キャッシュが減少することはありません。

インデックス プリフェッチには、メリットが得られないクエリにオーバーヘッドが追加されないように、次の安全対策が組み込まれています。

  • プリフェッチは LIMIT 句の境界で停止するため、スキャンはクエリが返す行を越えてページを読み取ることはありません。
  • カバリング インデックスのインデックスのみのスキャンの場合、AlloyDB はインデックス ページのみをプリフェッチし、テーブルページは読み取りません。
  • 主キーのルックアップなど、1 行を返すクエリではプリフェッチはトリガーされません。

ワークロードのメリット

インデックス プリフェッチは、ワーキング セットがインスタンスのメモリよりも大きく、クエリが B ツリー インデックスを介して多くの行を読み取る場合に最も効果的です。メリットが得られるクエリの例を次に示します。

  • インデックス付きのタイムスタンプ、日付、数値列に対する範囲クエリ(期間にわたるレポートなど)。
  • 1 つのキーに対して多くの行を返すクエリ(顧客の注文履歴など)。
  • 内部が多数の行を返すインデックス スキャンである結合。
  • 行指向テーブルから広範囲を読み取る分析クエリ。

データがすでに共有バッファにあるクエリと単一行ルックアップは、プリフェッチの有無にかかわらず同じように実行されます。

実行プランでのプリフェッチ

クエリに対するインデックス プリフェッチの効果を確認するには、EXPLAIN (ANALYZE, BUFFERS) を指定してクエリを実行します。プリフェッチによってローカル SSD キャッシュに読み込まれるページは、プランのインデックス スキャン ノードに ultra fast cache hit カウントとして表示されます。これらのカウンタの読み取りの詳細については、実行プランを取得して分析するをご覧ください。

次のステップ