ほぼすべての検索システムは、すでに運用しているPostgresのpgvectorから始めるべきであり、選定の問いは「どのベクトルデータベースが最速か」ではなく「どの障害モードが最初に自分に届くか」である。公表されているrecallやQPSの数値は、大半のチームが実際に運用するスケールではエンジン間で収束する。収束しないのは、すべてのクエリにテナントフィルタを付けたとき、営業時間中にインデックスの再構築が必要になったとき、HNSWグラフがRAMに収まらなくなったときに何が起きるかだ。移行を強いるのはこうした出来事であり、エンジンごとに壊れる箇所が違う。

したがってベクトルストアを正直に比較するなら、壊れる場面から逆算するのが筋だ。最初にぶつかる障害を特定し、それを持たないエンジンを選ぶ。それ以外はただの機能比較表である。

実際に壊れる4つのもの

本番のRAGやエージェントメモリのシステムを見渡すと、最初の選択からの移行のほぼすべては4つの症状に行き着く。

  • インデックスの構築と再構築の時間。埋め込みモデルを変える、次元数を変える、距離演算子を変える。すると全行に対して近似最近傍インデックスを作り直すことになる。100万ベクトルならコーヒー1杯の時間だ。5,000万ならメンテナンスウィンドウの話になり、新しいインデックスの構築中に古いインデックスでトラフィックを捌くかどうかを決めなければならない。
  • フィルタ付き検索のrecall。本番でフィルタなしのベクトルクエリを走らせる者はほぼいない。実際のクエリは「where tenant_id = X and status = active and updated_at > Y での最近傍」だ。グラフインデックスはフィルタなしのケースのために作られており、選択性の高いフィルタが入るとANN検索は要求したk件より少ない行を、しかも黙って返すことがある。これは関連性の問題の顔をした正しさの問題である。
  • グラフのメモリ消費とRAM。HNSWはグラフであり、メモリ上に住みたがる。グラフとワーキングセットの合計がインスタンスの搭載量を超えると、レイテンシは緩やかに劣化するのではなく、プローブのたびにインデックスページをディスクから読み始めた瞬間に崖から落ちる。
  • 書き込み負荷下でのフレッシュネスの遅延。エージェントメモリやサポートツールは常時書き込む。挿入のたびにグラフが変異し、インデックスのメンテナンスはクエリのトラフィックと競合し、「事実を保存した」と「事実を取得できる」の間のギャップが、体感ではなく正しさの問題として効いてくる。

このリストに載っていないものに注意してほしい。生のクエリ毎秒だ。取得結果を渡した先のモデルが生成に2秒かけるなら、検索レイテンシの10ミリ秒の差はノイズである。The latency that hurts in RAG lives in the number of round trips で書いたとおり、RAGで痛むレイテンシはラウンドトリップの数にあり、ANNのプローブにはない。

pgvector: 正しいデフォルトと、その本当の天井

pgvector を推す理由はベンチマークで勝つからではない。埋め込みが、それが説明する行と同じトランザクションの中にあり、フィルタはすでにインデックスの張られたカラムに対する普通のSQLで、バックアップとポイントインタイムリカバリはすでに運用しているものそのままで、オンコール担当はEXPLAINの読み方をすでに知っている。この組み合わせは相当な量のp99に値する。

天井は具体的で、暗記する価値がある。天井そのものよりも、それに対する漠然とした恐れのほうが、早すぎる移行を多く引き起こしているからだ。

  • 次元の上限はインデックスの上限であって、カラムの上限ではない。vectorカラムは最大16,000次元を受け付けるが、HNSWとIVFFlatがインデックスできるのは2,000次元までだ。halfvec(16ビット浮動小数点)を使えば、およそ半分のストレージで4,000次元までインデックスできる。bitはバイナリ量子化向けに64,000次元まで、sparsevecは非ゼロ要素1,000個までを扱う。3,072次元の埋め込みはPostgresを離れる理由ではなく、インデックス式でhalfvecにキャストする理由である。
  • フィルタ付きクエリは0.8.0で崖ではなくなった。昔の障害は実在した。HNSWスキャンがef_search個の候補を返し、WHERE句がその大半を消し、10件頼んだのに3件しか返ってこない。pgvector 0.8.0 は反復インデックススキャンを追加し、生き残る行が十分な数に達するまでスキャンを続けるようになった。hnsw.iterative_scan = strict_orderは正確な距離順を保ち、relaxed_orderは順序を少し犠牲にしてrecallを上げる。pgvectorのフィルタリングに対するメンタルモデルが2024年のままなら、それは時代遅れだ。
  • 実際に噛みつくのは構築時のメモリだ。HNSWはグラフがmaintenance_work_memに収まる間はメモリ上で構築され、収まらなくなるとはるかに遅いディスク上の経路にフォールバックする。対処は構築時にこの値を引き上げて並列ワーカーを使うことだが、あるサイズを超えると、再構築は実行するものではなく計画するものになる。
  • ノイジーネイバーはアーキテクチャの問題だ。チェックアウトフローを捌くインスタンスでANN構築がCPUを飽和させるのは、ベクトルとは何の関係もない障害モードである。リードレプリカか別インスタンスで解決するが、それはpgvectorが無料でなくなる瞬間でもある。

特にAWSでは、pgvector付きのAurora PostgreSQLは第一級の Bedrock Knowledge Basesのベクトルストア であり、これを選んでもマネージドRAGの機能を何も失わない。コスト面は the OpenSearch Serverless to Aurora migration post に書いたが、下で1つ但し書きがある。あの比較のOpenSearch側は2026年5月に変わった。

OpenSearch: 買っているのは検索エンジンなのだから、検索エンジンとして使う

純粋なベクトルストアとしてOpenSearchを選ぶのは、ベクトル検索を手に入れる高くつく方法だ。検索が必要で、ベクトルは検索に使う道具の1つだから選ぶ。それはまったく別の、はるかに良い判断である。

純粋なベクトルストアにはないものをOpenSearchは与えてくれる。ANNと並ぶ本物の字句検索。BM25とベクトル類似度を組み合わせるハイブリッド検索が、アーキテクチャではなく1本のクエリで済む。埋め込みが苦手なことで有名な部品番号、エラーコード、識別子の完全一致。後付けではなく、高カーディナリティ属性のために作られた集約、ファセット、フィルタリングエンジン。そしてバイナリベクトル。Bedrock Knowledge Basesでこれをサポートするのは2つのOpenSearchオプションだけだ。

反対論は歴史的に下限の話だった。OpenSearch ServerlessはOCUで課金され、ドキュメントを1件もインデックスしないうちから本番最低構成が実費を食った。私の移行記事はその議論の上に建っており、訂正が要る。次世代のOpenSearch Serverlessは2026年5月28日に一般提供が始まり、コンピュートとストレージが完全に分離され、スケールトゥゼロに対応し、AWSが前世代の20倍速いと説明するオートスケーリングを備える。AWSは、ピーク負荷向けにクラスタをプロビジョニングする場合と比べて最大60パーセントの節約を謳う。ワークロードがバースト的なら、そしてエージェントの検索は極めてバースト的だが、私が展開した形の下限論はもはや成り立たない。

それでも壊れるものはある。これはシャード、レプリカ、クラスタ状態を持つ分散システムであり、いずれその3つすべてについて考えることを求めてくる。ベクトルワークロードのシャードサイジングはログのそれと同じではない。そして再構築はreindexであり、インデックス2部分のキャパシティプランニングを意味する。

S3 Vectors: クエリに答えるストレージ層であって、サービング層ではない

S3 Vectorsは2025年12月2日に一般提供に到達した。プレビューの40倍のスケール、つまりインデックスあたり最大20億ベクトル、ベクトルバケットあたり1万インデックスで、2026年3月にはさらに17リージョンが追加された。AWSはベクトルデータベースを運用する場合と比べたコスト削減を最大90パーセントと置くが、その理由は宣伝ではなく構造にある。クラスタがなく、プロビジョンドコンピュートがなく、アイドル課金がない。

適否を決める数字はレイテンシプロファイルだ。AWSのドキュメントでは、頻度の低いクエリは1秒未満、より頻繁なクエリはおおむね100ミリ秒以下で返るとされる。これはウォームキャッシュ効果として読み、そのうえで自分のトラフィックに正直になることだ。1時間に40問しか聞かれないサポートアシスタントは、何もウォームに保てない。1秒未満は夜間の要約ジョブには十分で、モデル自身がさらに2秒を必要とする対話型チャットには不適切である。

本当に正解になる場面もある。コールドまたはアーカイブのベクトル層。テナント数が多く各テナントのトラフィックが疎な、テナントごとのインデックス。レイテンシ予算に余裕のあるコスト優先のBedrock Knowledge Bases。そして代替案がアイドル状態のクラスタへの支払いだったすべてのケース。ホットストアの下の第2層としてよく組み合わさるので、丸ごとの置き換えではなく、私ならそう使う。

Qdrant、Milvus、Pinecone: ペイロードが勝つとき

Postgresを離れて専用エンジンに向かうのは、ベクトルワークロードがアプリケーションの一機能であることをやめ、アプリケーションそのものになったときだ。その形は3つある。

Qdrantは、フィルタリングが問題のときに手を伸ばすものだ。ペイロードインデックスとフィルタ可能なHNSWは、pgvectorの反復スキャンがかろうじて生き延びるにすぎないケース、つまり毎クエリに選択性の高いフィルタが高頻度でかかるケースのために設計されている。スカラー、プロダクト、バイナリの量子化も同梱しており、大きなインデックスをメモリ常駐に保つ現実的な手段になる。すべての読み取りにテナント別フィルタがかかるマルチテナントのエージェントメモリストアなら、もう1つデータベースを運用する理由として十分に弁護できる。

Milvusは10億スケールの答えだ。ディスクベースのインデックス(DiskANN)によりワーキングセットがRAMに収まる必要がなくなり、そのサイズではそれがハードウェアの請求額を変える。引き換えは運用だ。コーディネータ、クエリ、データ、インデックスの役割が分かれた分散システムであり、これを本番で回すのは技術的判断である前に人員配置の判断である。数億ベクトルに満たない規模では、その複雑さはほとんど何も買ってくれない。

Pineconeは作らずに買う選択肢であり、他のSaaSと同じ流儀で、レイテンシではなく取り除いてくれる運用負荷で評価すべきだ。サーバーレス課金はストレージと読み書きを分離し、アイドルコストがないため、スパイクの多いワークロードに合い、小規模デプロイは本当に安くなる。手放すのは障害モードへのコントロールで、引き受けるのはegressとベンダー結合だ。Bedrock Knowledge Basesのサポート対象ストアでもあるので、AWSマネージドRAGの道からの離脱にはならない。

ロングテールを手短に

Weaviateは電池込みのRAGストアに最も近い。組み込みのベクトル化モジュール、ハイブリッド検索、スキーマファーストのモデル。意見を供給してほしいなら魅力的で、埋め込みパイプラインをすでに持っているならそれほどでもない。Chromaはそれを自認するプロトタイピングツールであり、私が見た本気のデプロイはどれも最終的にそこから移行した。Redisのベクトル類似検索は、ベクトルが短命なとき、つまりセッション、短期のエージェントメモリ、セマンティックキャッシュには優れ、システムオブレコードとしては最悪だ。MongoDB Atlas Vector SearchのMongoにおける位置づけは、pgvectorのPostgresにおけるそれと同じである。ドキュメントがすでにそこにあるなら正しく、ないならMongoを採用する理由としては貧弱だ。Redis Enterprise CloudとMongoDB Atlasは、どちらもBedrock Knowledge Basesのサポート対象ストアである。

判断表

エンジン適所最初に壊れるもの運用者
pgvector約5,000万ベクトル未満、フィルタはSQL、データはすでにPostgresにあるインデックス構築メモリと再構築ウィンドウ。ANNとOLTPの競合既存のDBAとオンコール
OpenSearch字句とベクトルのハイブリッド、ファセット、バイナリベクトルシャードとクラスタ状態の管理。reindexのキャパシティ検索クラスタを知っている誰か
S3 Vectorsコールド層、疎なテナント別インデックス、コスト優先のKnowledge Basesクエリ頻度の低いインデックスでの対話型レイテンシ誰もいない。それが要点
Qdrant毎クエリの選択的フィルタ、量子化した常駐インデックスステートフルなシステムをもう1つ運用することになる自分、またはQdrant Cloud
Milvus約5億ベクトル超、ディスクベースのインデックス多役割の分散システムという運用面専任のプラットフォームエンジニア
Pineconeスパイクの多いトラフィック、ステートフル運用をやる気がない高ボリューム持続時のコストカーブ。ベンダー結合Pinecone

「今すぐpgvectorを離れろ」を本当に意味するトリガー

抽象的なスケールの話ではない。次のものだ。

  • maintenance_work_memをすでに引き上げ、並列ワーカーも使ったうえで、HNSWの再構築が許容できるメンテナンスウィンドウに収まらなくなった。
  • 反復スキャンを有効化し、ef_searchをチューニングしてもフィルタ付きのrecallが足りない。フィルタの選択性が高すぎて、グラフという構造自体が間違っているからだ。
  • インデックスのワーキングセットがインスタンスのメモリを超え、1つ上のインスタンスサイズが専用エンジンより高くつく。
  • ベクトル検索がトランザクションワークロードを飢えさせており、リードレプリカでは分離が足りない。
  • 字句とベクトルを組み合わせたハイブリッドランキングを、アプリケーションコードでマージする2回の検索ではなく、第一級のクエリとして必要としている。これは特にOpenSearchを指すトリガーだ。

どれにも当てはまらないなら、計画中の移行は要件ではなく好みである。すでに運用しているデータベースの上で動く検索層を出荷し、トリガーのどれかが発火したときにだけ動くチームは、最初のスプリントを選定に費やしたチームよりかなり早く本番に到達する。

要点

pgvectorから始め、その4つの天井を、本物の限界と伝承を見分けられる程度に正確に知っておく。類似度ではなく検索が必要になったらOpenSearchに移り、コスト比較は昔のOCU下限ではなく次世代サーバーレスに対してやり直す。S3 Vectorsはコールド層と疎なテナント別インデックスに使い、対話型のサービング経路には使わない。フィルタリングが支配的ならQdrant、RAMが請求額を決める規模を超えたらMilvus、運用を回すより買いたいならPineconeに手を伸ばす。最初にぶつかる壊れ方で選ぶこと。この比較でエンジン間に意味のある差が出る変数は、それだけだからだ。

次に読む

本番でPostgresや検索クラスタを運用するインフラ側の話は、クラウドのフィールドノート ercan.cloud にあり、ハブは ercanermis.com にある。

参考資料