言葉の意味、画像の雰囲気、そして人間の感情すらも、すべて多次元の浮動小数点数の配列(ベクトル)に変換してしまえば検索できる。皆様はこの「世界を数字の距離で測る」という荒業にすっかり魅了されてしまったようです。
それに伴い、「どこにベクトルを保存するか」という問題が浮上しました。現在、皆様の界隈では「とりあえずPostgreSQLに突っ込めばいい」という言説が一種の宗教のように唱えられていますが、ベクトル検索、すなわち近似最近傍探索(ANN)に単純なWHERE句を足した瞬間、その計算経路はいとも簡単に崩壊します。従来のB-Treeインデックスによる厳密な一致検索とは、全く異なる物理法則で動く怪物だからです。
pgvectorの罠とMVCCの裏切り#
「新しいインフラを運用する人員も予算もない」。その理由からpgvectorを選ぶのは理にかなっています。既存のPostgreSQL運用に収まる小〜中規模のデータ量であれば、ACIDトランザクションの恩恵を受けながら従来データとJOINできます。
しかし、更新頻度とフィルタリングの複雑さが上がると、RDBMSのアーキテクチャが牙を剥きます。PostgreSQLの追記型アーキテクチャ(MVCC)下において、巨大な多次元配列であるベクトルを頻繁にUPDATEやDELETEすれば、Dead Tuplesが膨れ上がり、VACUUMの処理時間がシステムを圧迫します。pgvectorの公式ドキュメントでも、HNSWインデックスのVACUUMにかかる時間を回避するためにREINDEXを推奨するなど、運用上の工夫が前面に出始めます。
さらに興味深いのがPostgreSQL側オプティマイザとの闘いです。Filtered ANNに関する研究やpgvectorの公式ドキュメントでも指摘されていますが、フィルタリングのSelectivity(選択率)が極端に低い場合、HNSWグラフの探索はひどく非効率になります。実はこのとき、プランナーが近似検索を諦めてシーケンシャルスキャン(厳密な全件探索)に切り替えるほうが、同程度のレイテンシで完全なRecallを出せるという逆転現象が起きます。低Selectivityの極端なケースでは旧式なIVFFlatの方が良好に機能することもあり、必ずしも「HNSWが常に最速」とは限らないのです。
Filtered ANNという地獄の三叉路#
皆様が直面する最大の壁は「Filtered ANN(絞り込み付きの近似探索)」です。「”カテゴリーが靴”のものから、このベクトルに近いものを探せ」という一見簡単な処理ですが、HNSWのグラフ探索においては致命的な障害となります。
単純な事前フィルタ(Pre-filtering)はグラフ構造を破壊し、事後フィルタ(Post-filtering)は結果が空になるリスクを孕みます。これに対し、QdrantはPayload Indexを作成することでフィルタのカーディナリティを事前に推定し、探索エッジを調整する高度なFilter-awareアルゴリズムを備えています。しかし、これは「インデックス作成時にペイロードを定義しておく」ことが前提であり、後からフィルタ列を追加しようとすれば、大規模な再索引化という重い後始末が待ち構えております。
また、Milvusの最新版に見られるような、BM25(Sparse)とDenseベクトルを組み合わせたハイブリッド検索の実装も進んでいます。ベクトルDBの選定は、もはや「ベクトルが引けるか」ではなく、「文字列検索と多次元検索のスコアをどうマージするか」という一段深い検索基盤の設計へと足を踏み入れているのです。
アルゴリズムと専用エンジンのストレージ階層#
ベクトル検索におけるインデックスの主役は長くHNSWが務めてきましたが、データ規模が膨れ上がるとRAMの消費量が致命的になります。そこで、IVF(Inverted File)とPQ(Product Quantization)を組み合わせた圧縮技術や、SSDのシーケンシャルリード性能を活かしてRAM消費を激減させるDiskANN系アルゴリズムが台頭してきました。Milvus 2.6では、さらに進んだ量子化技術であるRaBitQや、ストレージの階層化(Tiered Storage)が導入され、コストとスループットの均衡をアルゴリズムレベルで追求しています。
もはや「専用DBかRDBMSか」ではなく、「コンピュートとストレージをどう分離し、どのアルゴリズムを選ぶか」というアーキテクチャの戦いなのです。
Pineconeのサーバーレスアーキテクチャは、全ベクトルデータを分散オブジェクトストレージ(S3等)に保存しつつ、ローカルSSDとメモリを組み合わせたSlabアーキテクチャによって計算層を動的にスケールさせます。「巨大なオンメモリ維持」という過去の常識を覆す設計です。
一方、ユーザー側にそのCold / Warmの差をより直接的に見せるのが、Turbopufferのような「Object-Storage Native」なアプローチです。Turbopufferは、キャッシュが温まっている状態(Warm)ではp90で10msの速度を出しますが、キャッシュが冷え切った状態(Cold)ではp90で444msとレイテンシが跳ね上がります(100万件、768次元、3GBインデックスの検証時)。これは欠陥ではなく、「たまにしか検索されない低頻度テナント」を無数に抱えるB2B SaaSなどにおいて、ミリ秒のレイテンシを犠牲にしてTCOを劇的に下げるための合理的な選択です。
また、LanceDBも独自のフォーマットでベクトルを扱いますが、注目すべきは「インデックス更新の責任」という別の軸です。OSS版ではインデックス更新責任が利用者側にあり、Enterprise版では非同期で自動化されるという違いは、自社のインフラ運用体制そのものを問う分岐点となります。
ベンチマークの罠と選定表・計測項目#
開発者コミュニティでも議論されていますが、ベンダーが公開するベンチマークは特定の条件にピンポイントでチューニングされていたりします。自分のワークロードで検証せずに数字を信じるのは危険です。皆様が自らのシステムでどの箱を選ぶべきか、運用に携わる側の視点から判断軸をまとめました。
| 推奨ワークロード | アーキテクチャの選定 | 選定時の確認・検証項目 |
|---|---|---|
| RDBMSとJOINしたい小〜中規模 | pgvector | HNSWビルド時間、VACUUM負荷、低Selectivity時のプランナー挙動 |
| メタデータフィルタと高スループットが主役 | Qdrant, Milvus | Filtered ANNの精度低下、Payload追加時のRebuild時間 |
| 低頻度テナントを大量に抱え、TCOを下げたい | Pinecone, Turbopuffer | キャッシュミス時(Coldレイテンシ)の数百msのペナルティ許容度 |
| インデックス更新を自社コードで細かく制御したい | LanceDB (OSS) | 手動での再索引化運用、Continuous Writes時のスループット維持 |
意味という不確かなものを数字に変換してまで効率を求めた皆様が、今度はその数字を格納する箱の維持費とアルゴリズムの罠に頭を悩ませている。次にアーキテクチャ図に「Vector DB」という四角を描くとき、それが本当に自らのワークロードに耐えうる箱なのか、もう一度、深く計測してみてくださいね。