PROD欧州主権の BaaS プラットフォームダッシュボードを開く →

ネイティブAI · 9 分読み取り

Postgres の HNSW インデックス: ベクトル検索用のインデックス ウェル

Affane Daylami · Fondateur · 2026年4月6日

ブログに戻る

HNSW は、pgvector が Postgres での類似ベクトル検索に推奨するインデックス アルゴリズムです。このガイドでは、適切に調整された HNSW インデックスを作成する方法を説明します。 3 つの選択が重要です。埋め込みのサイズに応じた列のタイプ、構築時の m パラメーターと ef_construction パラメーター、そしてリコールとレイテンシーを調整するための各リクエスト時の ef_search です。

この英語のテキストはフランス語のオリジナルから自動的に生成されたもので、まだレビューされていません。
このページは自動翻訳されました。英語版が正式です。

Aurabase のネイティブ ベクター検索 (RAG、pgvector、embeddings) は、これと同じインデックス作成メカニズムに依存しています。詳しくは、Postgres のネイティブ AIページで説明されています。このガイドでは、 pgvector がすでにインストールされている Postgres テーブル、 vector型の列、および少なくとも数千行を想定しています。以下に示すように、単純な順次スキャンは、多くの場合、近似インデックスよりも高速です。

必需品

  • IVFFlat とは異なり、HNSW はトレーニング フェーズを必要としません。インデックスは挿入によって構築され、バージョン 0.5.0 以降の pgvector で利用できます。
  • m (ノードごとの接続数、デフォルト 16) と ef_construction (構築時の検索幅、デフォルト 64) という 2 つのパラメータにより、構築時のインデックスの品質が設定されます。
  • 3 番目のパラメーター hnsw.ef_search (pgvector のデフォルト: 40) は、インデックスを再構築せずにリクエストごとに調整され、リコールとレイテンシーを調整します。
  • pgvector は、タイプ vector の HNSW インデックスを 2000 次元に制限します。それを超えると (たとえば、3072 次元の埋め込み)、インデックスを作成するには halfvec へのキャストが必要になります。
  • pgvector 0.8.6 は、Aurabase Postgres テナント イメージに埋め込まれているバージョンで、2026 年 8 月 24 日に Dockerfile で直接検証されました。
#
理解する

pgvector の HNSW インデックスとは何ですか?

HNSW は Hierarchical Navigable Small World の略です。これはグラフのインデックスです。各ベクトルは、最も近い近傍に接続されたノードとなり、いくつかの重ねられたレイヤーに編成されます。検索はグラフの最上部の最もまばらな層から開始され、次に層ごとに下降して最も関連性の高い近傍に到達します。したがって、検索時間は行数に対して線形ではなく、ほぼ対数になります。

pgvector のもう 1 つのインデックスである IVFFlat は、動作が異なります。インデックスを付ける前に、ベクトル空間を既存のサンプルのトレーニング パスによって決定されたリストに分割します。 HNSW にはこの制約がなく、挿入するたびにグラフが直接強化されるため、継続的に増大するテーブルの操作が簡単になります。一方、HNSW インデックスは、同じボリューム上の同等の IVFFlat よりも多くのメモリを消費し、構築に時間がかかります。

pgvector は、バージョン 0.5.0 で HNSW サポートを導入しました。新しいバージョンでは、このガイドに便利な機能が追加されています。2000 次元を超えるインデックスを作成する halfvec タイプ (0.7.0) と、フィルターされたクエリの再現率を向上させる hnsw.iterative_scan パラメーター (0.8.0) です。決定する前に pgvector を専用のベクター ベースと比較する場合は、pgvector と Pinecone、Weaviate、Qdrant の比較 でトレードオフを詳しく説明します。

#
ステップ1

インデックスを作成する前に pgvector のバージョンを確認してください

最初にインストールされている pgvector のバージョンを確認します。拡張機能が古すぎると、このガイドの一部の機能、特に halfvec と hnsw.iterative_scanが通知なしで失敗します。

psqlsql
SELECT extversion FROM pg_extension WHERE extname = 'vector';

HNSW は pgvector 0.5.0 から存在します。 2000 次元を超える埋め込みのインデックス付けに必要な halfvecタイプには、少なくともバージョン 0.7.0 が必要です。 hnsw.iterative_scan パラメータはバージョン 0.8.0 を要求します。

Aurabase プロジェクトでは、この疑問は生じません。Postgres イメージには、共有 Postgres クラスター (docker/Postgres.Dockerfile、 pgvector/pgvector:0.8.6-pg16-bookworm上に直接構築) とプロジェクトごとに専用の Postgres 16 CNPG インスタンス (docker/Postgres.CNPG.Dockerfile、公式 CloudNativePG イメージから pgvector 0.8.6 を継承) の両方に pgvector 0.8.6 が埋め込まれています。 2026 年 8 月 24 日に両方の Dockerfile で検証されました。

#
ステップ2

埋め込みのサイズに応じて適切なタイプの列を選択してください

列のタイプは、埋め込みを生成するモデルだけでなく、埋め込みのサイズによっても異なります。 pgvector は、クラシック ベクトルを vector型で保存し、ストレージ内の次元の上限は 16,000 です。ただし、このタイプの HNSW インデックス作成は 2000 次元に制限されており、それを超えると CREATE INDEX は失敗します。

一般的な埋め込みモデルは、このしきい値を超えることがよくあります。OpenAI の text-embedding-3-large または Google の gemini-embedding-2 は、ネイティブで最大 3072 次元を生成します。 HNSW を使用してこれらのベクトルにインデックスを付けるには、列を halfvec (ストレージ精度は半分) にキャストします。これにより、インデックス付けの制限が 2000 次元を大幅に超えます。

寸法コラムベクトル上の HNSWキャストが必要です
768埋め込み_768はいいいえ
1536埋め込み_1536はいいいえ
3072埋め込み_3072いいえ (> 2000 ディム)はい、キャスト::halfvec(3072)

Aurabase RAG エンジンは、本番環境でのこの妥協を示しています。サポートされている 3 つのクラスのディメンション (768、1536、3072) は、同じ embeddingsテーブルの 3 つの異なる列に格納されています。列 768 と 1536 は、vectorタイプの HNSW で直接インデックス付けされます。列 3072 は、2000 次元の上限を正確に回避するために、::halfvec(3072)キャストによってインデックスが付けられます。

migration.sqlsql
CREATE INDEX idx_embeddings_vec_768 ON embeddings
  USING hnsw (embedding_768 vector_cosine_ops)
  WHERE embedding_768 IS NOT NULL;

CREATE INDEX idx_embeddings_vec_1536 ON embeddings
  USING hnsw (embedding_1536 vector_cosine_ops)
  WHERE embedding_1536 IS NOT NULL;

CREATE INDEX idx_embeddings_vec_3072 ON embeddings
  USING hnsw ((embedding_3072::halfvec(3072)) halfvec_cosine_ops)
  WHERE embedding_3072 IS NOT NULL;

For details of ingestion (chunking, call to the embedding provider, insertion), see the RAG pipeline tutorial on pgvector.

#
ステップ3

m および ef_construction パラメータを使用してインデックスを作成します。

最初のインデックスには、デフォルト値の pgvector を使用した最小限の構文で十分です。

psqlsql
CREATE INDEX ON items
  USING hnsw (embedding vector_cosine_ops);

次に、 pgvector は m = 16 および ef_construction = 64を適用します。これらの値を明示的に調整するには、WITH 句を使用します。

psqlsql
CREATE INDEX ON items
  USING hnsw (embedding vector_cosine_ops)
  WITH (m = 24, ef_construction = 100);
大規模な建設を加速する

大きなテーブルに HNSW インデックスを構築する前に、セッションの maintenance_work_mem を一時的に増やします。これは、pgvector のドキュメント自体によると、構築時間を短縮するための最も直接的な手段です。

パラメータ m は何を変更しますか?

m は、グラフ内の各ノードがレイヤーごとに維持する接続の最大数を設定します。値が大きいほどグラフが緻密になります。再現率は増加しますが、消費されるメモリと構築時間もほぼ直線的に増加します。デフォルト (16) はほとんどの場合に適しています。 24 または 32 に上げることは、近くの隣と遠い隣の区別がより細かくなる大規模な埋め込みでは特に正当化されます。

ef_construction は何を変更しますか?

ef_construction は、挿入されたノードごとに、インデックスの構築中に探索される候補リストのサイズを設定します。値を大きくすると、最終的なグラフの品質が向上し、結果として潜在的な再現率が向上しますが、構築時間は長くなります。 mとは異なり、このパラメーターにはクエリ時にコストがかかりません。これは 1 回限りの投資であり、インデックスの作成時に 1 回だけ支払われます。

同じテーブル内の複数のディメンション クラスの部分インデックス

テーブルに複数のベクトル列 (Aurabase のようにディメンション クラスごとに 1 つ) が格納されている場合は、WHERE colonne IS NOT NULL句を使用して各列を個別にインデックス付けします。この部分インデックスにより、特定の行で使用されていないクラスの空行のインデックス作成が回避され、インデックスのサイズが削減され、リコールにコストがかからずにインデックスの構築が高速化されます。

演算子クラス (vector_cosine_ops、 vector_l2_ops または vector_ip_ops) の選択は、埋め込みモデルがトレーニングされたメトリックに対応する必要があります。最新のテキスト埋め込みモデルは、コサイン類似度を考慮してトレーニングされています。したがって、vector_cosine_ops (またはキャスト列の halfvec_cosine_ops) が最も安全なデフォルトの選択です。

ef_search は、インデックスの構築時ではなく、クエリごとに設定されます。検索中に探索される候補のリストのサイズを設定します。値が大きいほど、待ち時間は長くなりますが、再現率は高くなります。 pgvector はデフォルト値を 40 に設定します。

psqlsql
SET LOCAL hnsw.ef_search = 100;

SELECT id, content
FROM embeddings
ORDER BY embedding <=> '[...]'::vector
LIMIT 10;

(名前空間、テナント、またはその他のメタデータ基準で) インデックスをスキャンした後に適用される WHERE フィルターとベクトル検索をクエリで組み合わせると、40 で十分になることはほとんどありません。 HNSW スキャンでは ef_search の生の候補が返され、フィルターはそれらの一部を破棄します。生き残る候補者が少なすぎると、最終的な LIMIT が不足してしまいます。

したがって、Aurabase RAG エンジンは、固定値 40: ef = max(top_k × 4, 64)を維持するのではなく、要求された top_kに従って ef_search を動的に拡張します。最も近い 5 つの結果の検索には ef_search = 64が使用されます。上位 50 件の検索には ef_search = 200を使用します。この式は、別のリコール/レイテンシーのトレードオフが必要なデプロイメントの環境変数ごとに調整可能です。

pgvector 0.8 では、これと同じ問題に対する 2 番目の手段である hnsw.iterative_scanが追加されています。 strict_order または relaxed_orderモードでは、検索は、固定された候補リストで停止するのではなく、フィルタリング後に十分な結果が収集されるまで徐々に検索範囲を広げます。 Aurabase はデフォルトで strict_orderで有効化しますが、コールはセーブポイントで保護されます。 pgvector の 0.8 より前のバージョンでは、このパラメーターが存在しないため、クエリは失敗せずに縮退モードで続行されます。

#
さらに進んでください

完全な RAG パイプラインを構築する

この HNSW インデックスは、チャンク化、埋め込み生成、取り込み、検索という完全な RAG パイプラインの一部にすぎません。 ステップバイステップ チュートリアル は、最初の挿入から類似性クエリまで、このパイプラインを pgvector 上でエンドツーエンドで構築します。 技術ドキュメント では、Postgres 上に構築された Aurabase のすべてのネイティブ AI 機能についても詳しく説明しています。

#
よくある質問

よくある質問

HNSW と IVFFlat: pgvector ではどちらを選択しますか?+
HNSW は、運用環境におけるベクトル検索ケースの大部分に適しています。つまり、等しいレイテンシでのリコールが向上し、事前のトレーニング フェーズがなく、継続的に増加するテーブルに対する耐性が優れています。 IVFFlat は、使用可能なメモリが非常に制限されている場合でも適切なままですが、一般にリコールが低下し、データ分布が大幅に変化した場合には再トレーニングが必要になります。
HNSW インデックス用に計画するメモリの量はどれくらいですか?+
大きさのオーダーは、m とインデックス付きベクトルの数に直接依存します。各ノードは、ベクトル自体に加えて、レイヤーごとに最大 m 個の接続を保存します。実際のボリュームの信頼できる推定値を得るには、データの代表的なサブセットにインデックスを構築します。次に、未測定の経験則に頼るのではなく、 pg_relation_size() を使用してそのサイズを測定します。
HNSW を使用して 2000 次元を超えるエンベディングにインデックスを付けることはできますか?+
ベクトル型に直接関係しない: pgvector は、この型で 2000 次元を超える HNSW インデックスの構築を拒否します。解決策は、インデックス作成時に列をhalfvec にキャストすることです。これにより、ストレージ精度が半分になり、インデックス作成の制限が押し上げられます。これはまさに、Aurabase の 3072 次元の埋め込みクラスの実稼働環境で使用されるアプローチです。

導入の準備はできていますか?

5 分でバックエンドが完成します。

クレジット カードは不要 · 500 MB 無料 · 50,000 MAU