カラム型エンジンを使用してベクトル検索を高速化する

ドキュメントのバージョンを選択してください。

スケーラブルな最近傍(ScaNN)インデックスまたは階層ナビゲーション可能なスモール ワールド(HNSW)インデックスを使用する場合、AlloyDB Omni カラム型エンジンを使用してベクトル検索を高速化できます。カラム型エンジンは、これらのベクトル インデックスの読み取り用に最適化されたインメモリ キャッシュとして機能します。

カラム型エンジンにインデックスをキャッシュすると、読み取り用に最適化されたインメモリ表現のインデックスからクエリが直接提供され、データベースがベクトル検索ワークロードで処理できる秒間クエリ数(QPS)が増加します。

HNSW は、PostgreSQL 17 以降を実行している AlloyDB Omni クラスタのカラム型エンジンでのみ使用できます。カラム型エンジンを使用する ScaNN には、このような制限はありません。

始める前に

  • google_columnar_engine.enabled データベース フラグと google_columnar_engine.enable_index_caching データベース フラグを on に設定して、カラム型エンジンとそのインデックス キャッシュ機能を有効にします。

    データベース フラグを設定するには、ALTER SYSTEM PostgreSQL コマンドを実行します。

    ALTER SYSTEM SET google_columnar_engine.enabled = 'on';
    ALTER SYSTEM SET google_columnar_engine.enable_index_caching = 'on';
    

    構成パラメータの変更を有効にするには、AlloyDB Omni で実行中のコンテナを再起動します。

    Docker

      sudo docker restart CONTAINER_NAME
      ```
    * { Podman }
    ```posix-terminal
      sudo podman restart CONTAINER_NAME
      ```
    
    
    

    For more information on setting flags, see Configure database flags.

  • Create a ScaNN index or Create an HNSW index in your database.

Add an index to the columnar engine

After enabling the columnar engine, you can add an existing index to the cache using the google_columnar_engine_add_index() SQL function.

To add an index to the columnar engine, run the following query:

SELECT google_columnar_engine_add_index('INDEX_NAME');

INDEX_NAME は、ベクトル インデックスの名前に置き換えます。

カラム型エンジンにインデックスを追加すると、このインデックスを使用するすべてのクエリがカラム型エンジンによって自動的に高速化されます。クエリで EXPLAIN (ANALYZE, COLUMNAR_ENGINE) プランを使用すると、ベクトルクエリがカラム型エンジンによって高速化されていることを確認できます。

キャッシュの使用状況を確認する

ベクトルクエリがカラム型エンジンによって高速化されていることを確認するには、クエリで EXPLAIN (ANALYZE, COLUMNAR_ENGINE) プランを使用します。

ScaNN 実行プランの例

カラム型エンジンに追加された ScaNN インデックスを使用するクエリの実行プランの例を次に示します。

EXPLAIN (ANALYZE TRUE, SCANN TRUE, COSTS FALSE, TIMING FALSE, SUMMARY FALSE, VERBOSE FALSE, COLUMNAR_ENGINE TRUE)
SELECT * FROM t ORDER BY val <=> '[0.5,0.5,0.5,0.5]' LIMIT 100;

--This contains details about ScaNN's usage from the columnar engine. Example:
------------------------------------------------------------------------------------------------------
 Index Scan using scann_idx on t t_1 (actual rows=100 loops=1)
      Order By: (val <=> '[0.5,0.5,0.5,0.5]'::vector)
      Limit: 100
      ScaNN Info: (... columnar engine nodes hit=6...)
      Columnar Engine ScaNN Info: (index found=true)
(5 rows)

出力に columnar engine nodes hitColumnar Engine ScaNN Info: (index found=true) が含まれている場合は、クエリにカラム型エンジンが使用されています。

HNSW 実行プランの例

実行プランには、カラム型エンジンから取得された要素の比率(elements_from_ce)やディスクから取得された要素の比率(elements_from_disk)などの指標を示す、それぞれのインデックスの [Columnar Engine HNSW Info] セクションが表示されます。

カラム型エンジンに追加された HNSW インデックスを使用するクエリの実行プランの例を次に示します。

EXPLAIN (ANALYZE, COLUMNAR_ENGINE) SELECT * FROM documents ORDER BY embedding <=> '[0.1, 0.2, 0.3, 0.4, 0.5]'::vector LIMIT 5;

--This contains details about HNSW's usage from the columnar engine. Example:
------------------------------------------------------------------------------------------------------
 Limit (actual rows=5 loops=1)
   ->  Index Scan using hnsw_idx on documents (actual rows=5 loops=1)
         Order By: (embedding '[0.1, 0.2, 0.3, 0.4, 0.5]'::vector)
         Columnar Engine HNSW Info: (index found=true elements_from_ce=385 elements_from_disk=0)
         Columnar Check: table is not in the columnar store
(5 rows)

レスポンスは、すべての要素がカラム型エンジンから取得され(elements_from_ce=385)、ディスクから取得された要素がない(elements_from_disk=0)ため、インデックスがカラム型エンジンによって高速化されていることを示しています。

INSERTUPDATEDELETE ステートメントなどのデータ変更によってキャッシュ エントリが無効になると、カラム型エンジンはハイブリッド アプローチを使用して精度とパフォーマンスを維持します。有効なキャッシュ ベクトルをメモリから直接読み取り、変更されたベクトルまたは新しいベクトルのみをディスクから取得します。

大量のデータを変更すると、キャッシュが更新されるまで、elements_from_disk が一時的に増加し、パフォーマンスが低下する可能性があります。

キャッシュされたインデックスを管理する

キャッシュされたインデックスのライフサイクルを管理するには、選択したタスクの SQL コマンドを実行します。

  • キャッシュを手動で更新するには、次のコマンドを実行します。

    SELECT google_columnar_engine_refresh_index('INDEX_NAME');
    
  • インデックスのステータスを確認するには、次のコマンドを実行します。

    SELECT google_columnar_engine_verify('INDEX_NAME');
    
  • キャッシュからインデックスを削除するには、次のコマンドを実行します。

    SELECT google_columnar_engine_drop_index('INDEX_NAME');
    
  • アクティブなインデックスを表示するには、次のコマンドを実行します。

    SELECT * FROM g_columnar_indexes;
    
  • パーティション分割されたインデックスを表示するには、次のコマンドを実行します。

    SELECT * FROM g_columnar_index_partitions;
    

INDEX_NAME は、インデックスの名前に置き換えます。

制限事項

カラム型エンジンで高速化された HNSW インデックスを更新すると、インデックス サイズの最大 2 倍のメモリが一時的に消費されることがあります。

次のステップ