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

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

AlloyDB Omni カラム型エンジンを使用すると、Scalable Nearest Neighbors(ScaNN)インデックスまたは Hierarchical Navigable Small World(HNSW)インデックスを使用する際にベクトル検索を高速化できます。カラム型エンジンは、これらのベクトル インデックスの読み取り最適化されたインメモリ キャッシュとして機能します。

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

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

始める前に

  • google_columnar_engine.enabledgoogle_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';
    

    変更を反映させるため、`systemd` マネージャー構成を再読み込みし、`alloydbomni` サービスを再起動します。 ```posix-terminal sudo systemctl restart alloydbomni18

    フラグの設定方法については、データベース フラグを構成するをご覧ください。

  • データベースに ScaNN インデックスを作成するか、HNSW インデックスを作成する

カラム型エンジンにインデックスを追加する

カラム型エンジンを有効にすると、google_columnar_engine_add_index() SQL 関数を使用して既存のインデックスをキャッシュに追加できます。

カラム型エンジンにインデックスを追加するには、次のクエリを実行します。

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 実行プランの例

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

次に、カラム型エンジンに追加された 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 倍のメモリが一時的に消費されることがあります。

次のステップ