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 の比較 でトレードオフを詳しく説明します。
インデックスを作成する前に pgvector のバージョンを確認してください
最初にインストールされている pgvector のバージョンを確認します。拡張機能が古すぎると、このガイドの一部の機能、特に halfvec と hnsw.iterative_scanが通知なしで失敗します。
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 で検証されました。
埋め込みのサイズに応じて適切なタイプの列を選択してください
列のタイプは、埋め込みを生成するモデルだけでなく、埋め込みのサイズによっても異なります。 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)キャストによってインデックスが付けられます。
For details of ingestion (chunking, call to the embedding provider, insertion), see the RAG pipeline tutorial on pgvector.
m および ef_construction パラメータを使用してインデックスを作成します。
最初のインデックスには、デフォルト値の pgvector を使用した最小限の構文で十分です。
次に、 pgvector は m = 16 および ef_construction = 64を適用します。これらの値を明示的に調整するには、WITH 句を使用します。
大きなテーブルに 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 を設定する
ef_search は、インデックスの構築時ではなく、クエリごとに設定されます。検索中に探索される候補のリストのサイズを設定します。値が大きいほど、待ち時間は長くなりますが、再現率は高くなります。 pgvector はデフォルト値を 40 に設定します。
(名前空間、テナント、またはその他のメタデータ基準で) インデックスをスキャンした後に適用される 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 機能についても詳しく説明しています。