ども jinyangです。
世の中はAI一色で、RAGを導入したりベクトルDBを使って意味的な検索をする手法がかなり浸透してきたと感じています。一方でそれに伴って、ベクトルDBの選択肢が増えてきました。Weaviate、Chroma、Qdrant... たくさんあって迷いますよね。
その中で気になっていたのが LanceDB です。Rust製の高速ベクトルDBで、組み込み型アーキテクチャとS3ネイティブ対応が特徴。しかし日本語での情報がまだ少ない。
そこで今回は、JQaRAデータセットを使って PostgreSQL の全文検索と LanceDB の BM25 検索の精度・速度を比較してみました。ただし、本記事の結果はあくまで特定の実装・環境下でのベンチマークであり、各検索エンジンの本来の性能を反映しているとは限りません。その点を踏まえてお読みください。
なぜ PostgreSQL 以外の選択肢を検討するのか
AWS Aurora での拡張機能の制約
AWSのフルマネージドサービス Aurora を使っている場合、pgroonga などの拡張機能の導入や更新に制約があります。特定バージョンでしか利用できなかったり、新機能の反映が遅れたりすることがあります。
したがって、BM25のような全文検索では標準となっているアルゴリズムを適用できません。
pgvector の Post-Filtering 問題
以前の記事 pgvectorのPost-filtering問題とその解決策 で紹介した通り、pgvector はインデックススキャン後に WHERE 句でフィルタリングを行う仕様(Post-Filtering)があります。
先にベクトル検索で近いナレッジを取得してきても、フィルタリング後に結果が数件しか残らないケースが発生します。
LanceDB の特徴
LanceDB は以下の特徴を持っています:
| 特徴 | 説明 |
|---|---|
| S3 | AWS公式ブログで10億ベクトル規模のユースケースが紹介 |
| 組み込み型 | SQLiteやDuckDBのように、別途サーバー不要 |
| Lance フォーマット | カラムナーフォーマットでベクトルとメタデータを同一テーブルに格納 |
評価実験
データセット:JQaRA
評価には JQaRA (Japanese Question Answering with Retrieval Augmentation) を使用しました。RAG 評価のための日本語 Q&A データセットです。
| 項目 | 値 |
|---|---|
| パッセージ数 | 144,372 |
| 質問数 | 1,667 |
| 質問あたり正解パッセージ数(平均) | 9.72 |
| ベースデータ | JAQKET(Wikipedia ベース) |
| ライセンス | CC-BY-SA-4.0 |
JQaRA は、質問に対して「どのパッセージを取得すれば回答に役立つか」を評価するため、検索システムの精度評価に適しています。
実験環境
▶︎ 実験環境の詳細を見る
- PostgreSQL: Docker コンテナ上で実行
- LanceDB: ローカルの MinIO(S3互換ストレージ)に接続
- 注意: AWS S3 を使用した場合はネットワークレイテンシが加算されるため、結果は異なる可能性があります
- 評価スクリプト: FastAPI 経由で各検索エンドポイントを呼び出し
評価対象の検索手法
| 手法 | 説明 | 備考 |
|---|---|---|
| PostgreSQL FTS | to_tsvector('simple') を使用した全文検索 |
Sudachiで分かち書き済みのtoken列を検索対象に |
| PostgreSQL Bigram | pg_bigm による N-gram 検索 |
|
| LanceDB BM25 | Tantivy ベースの BM25 検索 |
評価メトリクス
- Recall@K: K件中に正解がいくつ含まれるか
- Precision@K: 取得した K件中の正解の割合
- F1@K: Recall と Precision の調和平均
評価結果
▶︎ 詳細な評価結果を見る
Recall@K
| Method | K=5 | K=10 | K=20 |
|---|---|---|---|
| PostgreSQL FTS | 0.221 | 0.298 | 0.377 |
| PostgreSQL Bigram | 0.067 | 0.095 | 0.134 |
| LanceDB BM25 | 0.251 | 0.346 | 0.459 |
Precision@K
| Method | K=5 | K=10 | K=20 |
|---|---|---|---|
| PostgreSQL FTS | 0.337 | 0.246 | 0.165 |
| PostgreSQL Bigram | 0.099 | 0.073 | 0.055 |
| LanceDB BM25 | 0.364 | 0.274 | 0.196 |
F1-Score@K
| Method | K=5 | K=10 | K=20 |
|---|---|---|---|
| PostgreSQL FTS | 0.267 | 0.270 | 0.230 |
| PostgreSQL Bigram | 0.080 | 0.082 | 0.078 |
| LanceDB BM25 | 0.297 | 0.306 | 0.274 |
実行時間: - PostgreSQL FTS: 888.04s (平均 532.7ms/query) - PostgreSQL Bigram: 3153.98s (平均 1892.0ms/query) - LanceDB BM25: 295.81s (平均 177.5ms/query)
結果の考察
精度比較
| メトリクス | PostgreSQL FTS | LanceDB BM25 | 差分 |
|---|---|---|---|
| Recall@5 | 0.221 | 0.251 | +13.6% |
| Recall@10 | 0.298 | 0.346 | +16.1% |
| Recall@20 | 0.377 | 0.459 | +21.8% |
今回の実験では、LanceDB の BM25 検索がすべての K 値で PostgreSQL FTS を上回りました。
速度比較
| 手法 | 平均レイテンシ |
|---|---|
| PostgreSQL FTS | 532.7ms |
| PostgreSQL Bigram | 1892.0ms |
| LanceDB BM25 | 177.5ms |
LanceDB が最も高速でした。
結果の解釈における注意点
今回の結果を解釈する際には、以下の点に注意が必要です:
1. PostgreSQL の検索条件は最適化されていない
- PostgreSQL の全文検索に関してはチューニングを全くしていない
- LanceDBの方も特段何か実装したわけではないが
2. アルゴリズムの違い
- PostgreSQL FTS: 単純なトークンマッチング(
simpleパーサー使用時) - LanceDB: BM25 によるスコアリング
本質的には「チューニングされていない PostgreSQL の基本的な全文検索」と「BM25 アルゴリズム」の比較という側面があります。
4. ストレージ環境
- LanceDB はローカルの MinIO に接続して実験
- AWS S3 を使用した場合、ネットワークレイテンシが加算されるため結果は異なる可能性がある
LanceDB の AWS 連携について
S3 との統合
LanceDB は AWS S3 をネイティブにサポートしており、オブジェクトストレージ上に .lance 形式のベクターテーブルを配置して直接クエリできます。これは LanceDB の ストレージと計算の分離設計を活かしたアーキテクチャです。
オブジェクトストレージ特有のレイテンシは避けられず、cold start(初回読み込み)時には S3 からのデータ取得に伴う遅延が発生する可能性があります。LanceDB OSS では内部キャッシュがないため、毎回 S3 との通信が発生しやすく、レスポンスが遅くなるケースも報告されています。
プロダクション環境では、ローカルディスクや NVMe SSD をキャッシュとして使う設計や Enterprise エディションのキャッシュ機能を利用することで、S3 からの読み込み頻度を下げてパフォーマンスを改善するのが一般的です。
まとめ
JQaRA データセットを使った評価実験を行いました。
今回の実験結果: - LanceDB BM25 は、今回の実装における PostgreSQL FTS と比較して Recall@10 で約16%高い精度 - クエリレイテンシは LanceDB が最も高速(ただしローカル MinIO 使用時)
BM25とPostgresのbuildinのts_rankを比較しただけの検証と結果的にはなっていますが、とにかくローコストで精度よく検索がしたいユースケースにおいては、LanceDBはs3のようなローコストなストレージを使って動かせることが何よりも魅力に感じますね.