すべてのプロダクト
Search
ドキュメントセンター

PolarDB:高次元ベクトル検索 (PASE)

最終更新日:Mar 29, 2026

PASE (PostgreSQL ANN search extension) は、PolarDB for PostgreSQL (Compatible with Oracle) に、パフォーマンス専有型の近似最近傍 (ANN) ベクトル検索機能を追加します。IVFFlat と HNSW (Hierarchical Navigable Small World) の 2 種類のインデックスタイプをサポートしており、ワークロードに合わせて速度と再現率のトレードオフを調整できます。

PASE は、指定されたベクターに対して類似検索を実行します。特徴ベクトルの抽出や生成は行いません。

前提条件

開始する前に、以下が準備されていることを確認してください。

  • PolarDB for PostgreSQL (Compatible with Oracle) クラスター

  • SQL ステートメントを実行するための特権アカウント

クイックスタート

以下の例は、拡張機能のインストール、テーブルの作成、インデックスのビルド、クエリの実行という一連のワークフローを示しています。

-- 拡張機能のインストール
CREATE EXTENSION pase;

-- ベクトル列を持つテーブルの作成
CREATE TABLE items (id integer, vector float4[]);

-- HNSW インデックスのビルド
CREATE INDEX hnsw_idx ON items
USING pase_hnsw(vector)
WITH (dim = 3, base_nb_num = 16, ef_build = 40, ef_search = 200, base64_encoded = 0);

-- 最近傍のクエリ
SELECT id, vector <?> '1,1,1:100:0'::pase AS distance
FROM items
ORDER BY vector <?> '1,1,1:100:0'::pase ASC
LIMIT 10;

インデックスタイプの選択

IVFFlatHNSW
最適な用途高精度シナリオ、画像比較大規模データセット (数千万以上のベクター)、レコメンデーションの再現率
目標クエリレイテンシー最大 100 ms10 ms 未満
ビルド時間高速低速
メモリ使用量下位多い (近接グラフを格納するため)
100% の再現率の可能性あり (クエリベクターがデータセット内に存在する場合)なし (精度は一定のレベルで頭打ちになる)
再設定可能な精度あり (クエリ時にプローブ数を調整)限定的

IVFFlat を使用する場合: 高い精度が必要で、最大 100 ms のクエリレイテンシーを許容でき、ストレージオーバーヘッドが少なく高速なインデックスビルドを求める場合に IVFFlat を選択します。

HNSW を使用する場合: クエリが 10 ms 以内に返される必要がある大規模データセットには HNSW を選択します。メモリ使用量が多くなり、インデックスのビルド時間も長くなることを想定してください。

仕組み

IVFFlat

IVFFlat は、IVFADC アルゴリズムの簡易版です。k 平均法を使用してベクターをクラスターに分割し、クエリ時には検索範囲をクエリベクターに最も近いクラスターに絞り込みます。

How IVFFlat works
  1. IVFFlat は k 平均法を使用してすべてのベクターをクラスタリングします。各クラスターには重心があります。

  2. クエリ時、IVFFlat はクエリベクターに最も近い *n* 個の重心を見つけます。

  3. IVFFlat は、それらの *n* 個のクラスター内のすべてのベクターを検索し、最も近い *k* 個を返します。

*n* 個のクラスターのみを検索することでクエリは高速化されますが、スキップされたクラスター内の類似ベクターを見逃す可能性があり、再現率が低下します。再現率を向上させるには *n* を増やしますが、その分計算量が増加します。完全な走査を避けるためにプロダクト量子化を使用する IVFADC とは異なり、IVFFlat は各クラスター内で力まかせ探索を使用して精度を維持します。

HNSW

HNSW は、NSW (Navigable Small World) アルゴリズムを使用して多層グラフを構築します。各レイヤーは、その下のレイヤーをより粗くしたビューです。

How HNSW works
  1. HNSW は、複数のレイヤーを持つ階層グラフを構築します。

  2. 検索は、最上位レイヤーのランダムなエントリポイントから開始されます。

  3. HNSW は、現在の要素の近傍を特定し、それらを距離でランク付けされた固定長の動的リストに追加します。次に、それらの近傍の近傍へと展開し、リストを継続的に再ソートして上位 *k* 個の候補のみを保持します。これはリストが安定するまで続き、その後、最上位の要素が次の下位レイヤーのエントリポイントになります。

  4. 最下位レイヤーが最終的な最近傍を返します。

HNSW の近傍選択アプローチは、大規模なデータセットにおいてクラスタリングベースのアルゴリズムよりも優れたクエリパフォーマンスを発揮しますが、近接グラフを格納する必要があるため、追加のメモリを消費します。

IVFFlat インデックスの作成

距離計算メソッドの選択

メソッド正規化が必要
ユークリッド距離0不要
ドット積 (内積)1はい

ドット積またはコサインメソッドを使用する場合は、まずベクターを正規化する必要があります。ベクター の場合、 を満たす必要があります。正規化後、ドット積はコサイン値と等しくなります。

PolarDB はネイティブではユークリッド距離のみをサポートしています。ドット積を使用するには、ベクターを正規化し、「付録」のアプローチに従ってください。

インデックスの作成

CREATE INDEX ivfflat_idx ON vectors_table
USING pase_ivfflat(vector)
WITH (
  clustering_type = 1,
  distance_type = 0,
  dimension = 256,
  base64_encoded = 0,
  clustering_params = "10,100"
);
内部クラスタリング (clustering_type = 1) を使用するには、インデックスを作成する前にテーブルにデータを挿入してください。

IVFFlat インデックスのパラメーター

パラメーター必須説明デフォルト値
clustering_typeはい0 = 外部クラスタリング (clustering_params で指定された重心ファイルをロード)。1 = 内部 k 平均法クラスタリング。PASE を初めて使用する場合は 1 から始めてください。
distance_typeいいえ0 = ユークリッド距離。1 = ドット積 (正規化されたベクターが必要。ドット積の順序はユークリッド距離の順序と逆)。0
dimensionはいベクトル次元数。最大:512。
base64_encodedいいえ0 = ベクターの表現に float4[] を使用。1 = Base64 エンコードされた float[] を使用。0
clustering_paramsはい外部クラスタリングの場合:重心ファイルへのパス。内部クラスタリングの場合:clustering_sample_ratio,k

内部クラスタリングのための `clustering_params` の設定:

  • clustering_sample_ratio:分母を 1000 としたサンプリング率。有効値:(0, 1000]。例えば、1 は 1/1000 のサンプリング比率を意味します。サンプリングされるレコードの合計は 100,000 未満にしてください。

  • k:重心の数。有効値:[100, 1000]。値を大きくすると再現率が向上しますが、インデックスの作成が遅くなります。

IVFFlat インデックスを使用したクエリ

<#> 演算子を使用すると、IVFFlat インデックスが有効になります。ORDER BY 句が必要です。

SELECT id, vector <#> '1,1,1'::pase AS distance
FROM vectors_ivfflat
ORDER BY vector <#> '1,1,1:10:0'::pase ASC
LIMIT 10;

クエリ文字列 'vector:probe_count:distance_type' は、コロンで区切られた 3 つのパラメーターを受け入れます。

位置説明範囲
1 番目クエリベクター
2 番目プローブ数 — 検索するクラスターの数。値を大きくすると再現率が向上しますが、クエリ速度は低下します。(0, 1000]
3 番目距離計算メソッド:0 = ユークリッド距離、1 = ドット積 (正規化されたベクターが必要)0 または 1

HNSW インデックスの作成

インデックスの作成

CREATE INDEX hnsw_idx ON vectors_table
USING pase_hnsw(vector)
WITH (
  dim = 256,
  base_nb_num = 16,
  ef_build = 40,
  ef_search = 200,
  base64_encoded = 0
);

HNSW インデックスのパラメーター

パラメーター必須説明デフォルト値
dimはいベクトル次元数。最大:512。
base_nb_numはい要素ごとの近傍の数。値を大きくすると再現率が向上しますが、ビルド時間とメモリ使用量が増加します。推奨範囲:[16, 128]。
ef_buildはいインデックス構築時のヒープサイズ。値を大きくすると再現率が向上しますが、インデックスの作成が遅くなります。推奨範囲:[40, 400]。
ef_searchはいクエリ時のヒープサイズ。値を大きくすると再現率が向上しますが、クエリ速度は低下します。クエリ時にオーバーライドできます。200
base64_encodedいいえ0 = ベクターの表現に float4[] を使用。1 = Base64 エンコードされた float[] を使用。0

HNSW インデックスを使用したクエリ

<?> 演算子を使用すると、HNSW インデックスが有効になります。ORDER BY 句が必要です。

SELECT id, vector <?> '1,1,1'::pase AS distance
FROM vectors_ivfflat
ORDER BY vector <?> '1,1,1:100:0'::pase ASC
LIMIT 10;

クエリ文字列 'vector:ef_search:distance_type' は、コロンで区切られた 3 つのパラメーターを受け入れます。

位置説明範囲
1 番目クエリベクター
2 番目ef_search のオーバーライド — 値を大きくすると、クエリ速度を犠牲にして再現率が向上します。40 から始めて、目標の再現率に達するまで増やしてください。(0, ∞)
3 番目距離計算メソッド:0 = ユークリッド距離、1 = ドット積 (正規化されたベクターが必要)0 または 1

ベクトル類似度の計算

PASE は、ベクトル類似度をインラインで計算するための 2 つのコンストラクターメソッドを提供します。

PASE 型構造

<?> 演算子は、左側に float4[]、右側に PASE 型を取ります。

SELECT ARRAY[2, 1, 1]::float4[] <?> pase(ARRAY[3, 1, 1]::float4[]) AS distance;
SELECT ARRAY[2, 1, 1]::float4[] <?> pase(ARRAY[3, 1, 1]::float4[], 0) AS distance;
SELECT ARRAY[2, 1, 1]::float4[] <?> pase(ARRAY[3, 1, 1]::float4[], 0, 1) AS distance;

PASE コンストラクターは、最大 3 つの引数 pase(vector, unused_param, distance_method) を受け入れます。2 番目の引数には特別な目的はありません。0 に設定してください。3 番目の引数は距離計算メソッドを設定します:0 はユークリッド距離、1 はドット積です。

両方のベクターは同じ次元数でなければなりません。不一致の場合はエラーが発生します。

文字列による構築

SELECT ARRAY[2, 1, 1]::float4[] <?> '3,1,1'::pase AS distance;
SELECT ARRAY[2, 1, 1]::float4[] <?> '3,1,1:0'::pase AS distance;
SELECT ARRAY[2, 1, 1]::float4[] <?> '3,1,1:0:1'::pase AS distance;

文字列フォーマットは 'vector:unused_param:distance_method' で、区切り文字としてコロンを使用します。パラメーターの意味は PASE 型コンストラクターと同じです。

注意事項

  • インデックスの肥大化: SELECT pg_relation_size('index_name'); でインデックスサイズを確認してください。インデックスがテーブルデータよりも大きく、クエリが遅くなっている場合は、インデックスを再ビルドしてください。

  • インデックスのドリフト: 頻繁なデータ更新はインデックスの精度を低下させる可能性があります。100% の精度が必要な場合は、定期的にインデックスを再ビルドしてください。

  • 並列クエリ: マルチノード弾性並列クエリでは、高次元ベクターに対してシーケンシャル検索のみがサポートされています。

  • 特権アカウント: このトピックのすべての SQL ステートメントには、特権アカウントが必要です。

付録

HNSW を使用したドット積の計算

PolarDB はネイティブでドット積距離をサポートしていないため、ベクターを正規化した後、この関数を使用してドット積で検索します。

CREATE OR REPLACE FUNCTION inner_product_search(
  query_vector text,
  ef integer,
  k integer,
  table_name text
)
RETURNS TABLE (id integer, uid text, distance float4) AS $$
BEGIN
  RETURN QUERY EXECUTE format('
    SELECT a.id, a.vector <?> pase(ARRAY[%s], %s, 1) AS distance
    FROM (
      SELECT id, vector
      FROM %s
      ORDER BY vector <?> pase(ARRAY[%s], %s, 0) ASC
      LIMIT %s
    ) a
    ORDER BY distance DESC;',
    query_vector, ef, table_name, query_vector, ef, k);
END
$$ LANGUAGE plpgsql;
正規化されたベクトルのドット積はそのコサイン値と等しくなるため、この関数はコサイン類似度検索にも使用できます。

外部重心ファイルからの IVFFlat インデックスの作成

外部クラスタリングは高度なオプションです。重心ファイルをサーバーにアップロードし、インデックス定義で clustering_type = 0 を設定します。

重心ファイルのフォーマットは次のとおりです。

次元数|重心数|重心ベクターデータセット

例:

3|2|1,1,1,2,2,2

参考文献