Vector DB比較 2026: Qdrant vs ChromaDB vs pgvector 選択ガイド

Vector DB比較 2026: Qdrant vs ChromaDB vs pgvector 選択ガイド

Qdrant・ChromaDB・pgvectorを1000ベクトル(dim=384)環境で直接ベンチマーク。挿入速度・クエリ遅延・フィルタ性能の実測値でRAGアプリの選択基準を示し、小規模でChromaDBが速い理由も解説する。

RAGアプリを初めて作るとき、ベクターDB選びは思ったより時間を取られる。「とりあえずChromaでいいか」から始まり、Qdrantのベンチマーク資料を見て揺らぎ、pgvectorのブログ記事を読んでまたPostgreSQLに戻ろうか悩む。その繰り返しだ。

実際に試してみないと答えは出ないと判断して、同じ条件で3つを計測してみた。1000ベクトル、dim=384、50回クエリの繰り返し。数字が小さく見えるかもしれないが、プロトタイプや小規模プロダクションでどのDBがどう動くかを確認するには十分だった。

RAGアプリでベクターDBがなぜ重要か

ベクターDB選択がなぜ重要かを最初に整理しておきたい。単に速ければいいという話ではない。

RAG(Retrieval-Augmented Generation)パイプラインでは、ベクター検索がユーザーのクエリ処理のクリティカルパスに位置する。ユーザーが質問を入力すると、埋め込み → ベクター検索 → コンテキスト構築 → LLM呼び出しの順で処理される。LLM呼び出しが1〜5秒を占めるため、ベクター検索の数ミリ秒の差が体感に大きく影響しないと思うかもしれない。

しかしそれは単純な検索の話だ。実際のプロダクションRAGには必ずメタデータフィルタが付く。特定ユーザーの文書だけを検索したり、特定の日付範囲のデータだけを取得したり、特定カテゴリーのみを含めるフィルタ。このフィルタクエリの遅延時間がDBの選択によって大きく変わる。

もう一つ、ベクターDBは単なるストレージ以上の設計判断だ。どのDBを使うかによってインフラ構成、デプロイの複雑さ、運用コスト、そして後でデータを移すマイグレーションの難易度が変わる。

RAGアーキテクチャ全体の設計を先に把握しておくと、この比較がより文脈をもって読める。RAGアーキテクチャの全体像を確認してからここに戻ってくるのもいい。

ChromaDB: 5分でセットアップ、でもプロダクションは?

ChromaDBは「5分でベクター検索」を掲げているが、実際にそのとおりだ。

pip install chromadb
import chromadb

client = chromadb.Client()
collection = client.create_collection("my_docs")

# ベクター挿入
collection.add(
    embeddings=[[0.1, 0.2, ...] * 384],  # dim=384
    metadatas=[{"source": "doc1", "category": "tech"}],
    ids=["doc1"]
)

# クエリ
results = collection.query(
    query_embeddings=[[0.1, 0.2, ...]],
    n_results=5,
    where={"category": "tech"}  # メタデータフィルタ
)

APIが直感的だ。addquerydeleteの3つで基本機能は揃う。メタデータフィルタもwhere辞書一つで簡単に表現できる。

ChromaDBの強み

インメモリモードがデフォルトなのでテストが速い。chromadb.PersistentClient(path="./db")でローカルファイル保存も簡単だ。クライアント-サーバーモードも対応していて、chromadb.HttpClient(host="localhost")に切り替えるだけでいい。

PythonエコシステムとのインテグレーションはLangChainやLlamaIndexで最も成熟している。参考資料も多く、詰まってもStack OverflowやGitHub Issuesですぐ解決できる。

ChromaDBの限界、正直に言うと

直接使ってみて、1万件を超えたあたりから感覚が変わり始めた。ChromaDBのデフォルトインデックスはHNSWだが、大量データでの最適化レベルはQdrantほど精巧ではない。

何より、ChromaDBをプロダクションで使っているチームが思ったより少ないと感じた。コミュニティでは「プロトタイプにはChroma、プロダクションにはQdrant」というパターンが繰り返される。これが過大評価の証拠とは言い切れないが、少なくとも100万件以上のスケールでの性能保証はQdrantやpgvectorと比べてリファレンスが少ない。

また、クラスタリング(水平スケール)を公式サポートしていない。シングルノードが限界だ。トラフィックが増えたときのスケールアウト戦略が制限される。

Qdrant: パフォーマンスを優先するなら

QdrantはRustで書かれたベクターDBで、最初からプロダクション規模を念頭に置いて設計されている。Dockerひとつで始められる。

docker pull qdrant/qdrant
docker run -p 6333:6333 qdrant/qdrant
from qdrant_client import QdrantClient
from qdrant_client.models import Distance, VectorParams, PointStruct, Filter, FieldCondition, MatchValue

client = QdrantClient("localhost", port=6333)

# コレクション作成
client.create_collection(
    collection_name="my_docs",
    vectors_config=VectorParams(size=384, distance=Distance.COSINE)
)

# ベクター挿入
client.upsert(
    collection_name="my_docs",
    points=[
        PointStruct(
            id=1,
            vector=[0.1, 0.2, ...],
            payload={"source": "doc1", "category": "tech"}
        )
    ]
)

# フィルタークエリ
results = client.search(
    collection_name="my_docs",
    query_vector=[0.1, 0.2, ...],
    query_filter=Filter(
        must=[FieldCondition(key="category", match=MatchValue(value="tech"))]
    ),
    limit=5
)

ChromaDBよりAPIが少し冗長だ。FilterFieldConditionMatchValueといったオブジェクトを直接組み立てる必要がある。最初は面倒に感じるが、複雑なフィルタ条件を表現するときにこの明示性がむしろ助けになる。

Qdrantの強み

HNSWインデックスの最適化は3つのDBの中で最も精巧だ。500万件以上のベクターではQdrantの検索性能の優位性が明確に出る。分散クラスタリングを公式サポートし、量子化(Product Quantization)でメモリ使用量を削減できる。ペイロードインデックスもサポートしているので大規模なメタデータフィルタが効率的だ。

REST APIとgRPCの両方をサポートし、管理UIも含まれている。localhost:6333/dashboardを開けばコレクションの状態をすぐ確認できてデバッグが楽だ。

Qdrantの限界

小規模ではオーバースペックになりうる。Docker自体の起動がChromaDBのインメモリと比べて敷居が高く、設定パラメータが多いのでチューニングに時間がかかる。私の実験でも、1000件規模のフィルタクエリはChromaDBより遅かった。この点は後のベンチマークセクションで詳しく説明する。

pgvector: すでにPostgreSQLを使っているなら

pgvectorはPostgreSQLの拡張機能だ。新しいベクターDBを追加するのではなく、既存のPostgreSQLにベクター検索機能を載せる。

-- 拡張のインストール
CREATE EXTENSION IF NOT EXISTS vector;

-- テーブル作成
CREATE TABLE documents (
    id SERIAL PRIMARY KEY,
    content TEXT,
    category VARCHAR(50),
    embedding vector(384)
);

-- HNSWインデックス作成
CREATE INDEX ON documents USING hnsw (embedding vector_cosine_ops)
WITH (m = 16, ef_construction = 64);

-- データ挿入
INSERT INTO documents (content, category, embedding)
VALUES ('ドキュメント内容', 'tech', '[0.1, 0.2, ...]');

-- ベクター検索(フィルタ付き)
SELECT id, content, 1 - (embedding <=> '[0.1, 0.2, ...]') AS similarity
FROM documents
WHERE category = 'tech'
ORDER BY embedding <=> '[0.1, 0.2, ...]'
LIMIT 5;

Pythonからはpsycopg2asyncpgで接続し、pgvectorライブラリを使う。

from pgvector.psycopg2 import register_vector
import psycopg2

conn = psycopg2.connect("postgresql://user:pass@localhost/db")
register_vector(conn)

cur = conn.cursor()
cur.execute(
    "SELECT id, content FROM documents WHERE category = %s ORDER BY embedding <=> %s LIMIT 5",
    ("tech", embedding_array)
)

pgvectorの強み

すでにPostgreSQLを使っているなら追加インフラがゼロだ。既存のORM、マイグレーションツール、バックアップ戦略、モニタリングシステムをそのまま使える。SQLの豊富なフィルタ表現力もそのまま活用できる。JOINが必要な場合も自然に書ける。たとえばユーザーテーブルとJOINして、特定ユーザーの文書だけ検索するようなケースだ。

pgvectorの限界

私はpgvectorが過大評価される傾向があると見ている。「PostgreSQLでベクターもできる」という利便性は本物だが、専用ベクターDBとの性能差はスケールとともに広がる。特にネットワークオーバーヘッドが問題だ。同一マシンで計測した私の実験値(numpy近似)とは異なり、実際にPostgreSQLサーバーが分離された環境ではクエリごとにネットワーク往復で10〜50msが追加される。これはQdrantやChromaDBのローカル計測値とは直接比較できない。

また、HNSWインデックスを適切にチューニングするにはPostgreSQLの専門知識が必要だ。mef_constructionef_searchパラメータの調整なしにデフォルトで使うと、期待を下回る性能になることがある。

直接実験してみたベンチマーク数値

以下の環境で計測した結果だ。

  • ベクター数: 1,000件
  • 次元数(dim): 384(sentence-transformers基準)
  • クエリ繰り返し: 50回
  • ハードウェア: MacBook Pro M2、ローカル実行
  • ChromaDB: インメモリモード
  • Qdrant: Docker(ローカル)
  • pgvector: numpy近似(実際のPostgreSQL環境ではネットワークオーバーヘッドが追加される)
import chromadb
import numpy as np
import time
from qdrant_client import QdrantClient
from qdrant_client.models import Distance, VectorParams, PointStruct

DIM = 384
N_VECTORS = 1000
N_QUERIES = 50

# テストデータ生成
np.random.seed(42)
vectors = np.random.randn(N_VECTORS, DIM).astype(np.float32)
vectors = vectors / np.linalg.norm(vectors, axis=1, keepdims=True)
query_vectors = np.random.randn(N_QUERIES, DIM).astype(np.float32)
categories = [f"cat_{i % 5}" for i in range(N_VECTORS)]

# ---- ChromaDB ベンチマーク ----
chroma_client = chromadb.Client()
collection = chroma_client.create_collection("bench")

# 挿入時間
start = time.perf_counter()
collection.add(
    embeddings=vectors.tolist(),
    metadatas=[{"category": c} for c in categories],
    ids=[str(i) for i in range(N_VECTORS)]
)
chroma_insert_time = time.perf_counter() - start

# 通常クエリ時間
query_times = []
for qv in query_vectors:
    t = time.perf_counter()
    collection.query(query_embeddings=[qv.tolist()], n_results=5)
    query_times.append((time.perf_counter() - t) * 1000)

# フィルタークエリ時間
filter_times = []
for qv in query_vectors:
    t = time.perf_counter()
    collection.query(
        query_embeddings=[qv.tolist()],
        n_results=5,
        where={"category": "cat_0"}
    )
    filter_times.append((time.perf_counter() - t) * 1000)

print(f"ChromaDB 挿入: {chroma_insert_time:.3f}s")
print(f"ChromaDB クエリ平均: {np.mean(query_times):.2f}ms, P95: {np.percentile(query_times, 95):.2f}ms")
print(f"ChromaDB フィルタークエリ平均: {np.mean(filter_times):.2f}ms")

実験結果

=== 挿入時間 ===
ChromaDB:  0.263s
Qdrant:    0.163s

=== 通常クエリ(50回平均)===
ChromaDB:  平均 0.80ms | P95 0.82ms
Qdrant:    平均 0.84ms | P95 1.88ms

=== フィルタークエリ(50回平均)===
ChromaDB:  平均 2.00ms
Qdrant:    平均 7.02ms

pgvector: numpy近似で1〜3ms(実際の環境は+10〜50msのネットワークオーバーヘッド)

ベンチマーク結果チャート

結果の読み方

最も驚いたのはフィルタークエリでChromaDB(2ms)がQdrant(7ms)より速かった点だ。最初は不思議に見えるかもしれない。Qdrantの方が精巧なシステムなのになぜ遅いのか?

理由はアーキテクチャの違いにある。Qdrantはペイロードインデックス、分散フィルタ、セグメント管理など大規模向けの構造を持っている。1000件のような小規模では、この精巧な構造が単純なブルートフォーススキャンよりもむしろオーバーヘッドになる。ChromaDBは小規模でより直接的な方法でフィルタを処理するため速い。

挿入はQdrantの方が速い(0.163s vs 0.263s)。Rust実装の優位性がここに出ている。

通常クエリは2つのDBで似たような数値だが、QdrantのP95が1.88msでChromaDBの0.82msより高い。小規模ではQdrantのテールレイテンシが大きい。

決定マトリクス: どの状況で何を使うか

数字だけ見ると「ChromaDBが常に優れている」という結論になりそうだが、実際の選択はもっと複雑だ。

状況推奨理由
プロトタイプ、ハッカソンChromaDBインストール即時、API単純、インメモリ
小規模プロダクション(10万件以下)ChromaDB または pgvectorシンプルさ優先
すでにPostgreSQL運用中pgvector追加インフラ不要
中規模(10〜500万件)Qdrant性能と安定性のバランス
大規模(500万件以上)QdrantHNSWの最適化、クラスタリングが必須
複雑なSQL JOINが必要pgvectorSQLの表現力
水平スケールが予想されるQdrant分散クラスタを公式サポート
最小の運用負担pgvector(既存Postgres)単一システム

詳細な選択基準

ChromaDBを選ぶ場合: 素早いPoC(概念実証)が目的、チームにDevOpsの余力がない、データ規模が数十万件を超えないことが確実なとき。LangChainやLlamaIndexと即座に連携するデモアプリには最適だ。

Qdrantを選ぶ場合: プロダクションのトラフィックを捌く必要があり、500万件以上のベクターが予想されるか、水平スケールが必要なとき。最初からQdrantで始めれば、後でマイグレーションなしにスケールアップできる。ただし小規模プロジェクトではDockerの運用コストがChromaDB比で実質的なオーバーヘッドになる。

pgvectorを選ぶ場合: すでにPostgreSQLインフラがあり、DBAがいて、ベクター検索が既存のSQLクエリと組み合わさる必要があるとき。「新しいベクターDBを学ぶ時間がない」というチームには最も現実的な選択だ。

埋め込みモデルの次元数(dim)の選択もDB性能に影響する。Gemini Embedding 2のようなマルチモーダル埋め込みを使う際にdim設計がどう変わるかは別途読む価値がある。

いつ使い、いつ避けるべきか

ベンチマークの数値と決定マトリクスだけでは、実際の選択は決まりきらない。そこで各DBを「こういう時に使う / こういう時は避ける」で整理した。

ChromaDBを使う時

  • 数日でRAGのPoCを作る必要があり、データ規模が数十万件を超えないことが確実な時
  • チームにDevOps人員がおらず、別途インフラを立てる余裕がない時
  • LangChain・LlamaIndexのチュートリアルをそのままなぞってデモを作る時

ChromaDBを避ける時

  • 100万件以上のベクターを安定してサービングする必要がある時。この規模のプロダクション実績は相対的に乏しい。
  • セルフホストでマルチノードの水平スケールアウトが必須の時。内蔵の分散クラスタがない。
  • 「categoryがtechかつscore 0.8以上かつ日付が特定範囲」のような複合フィルタをコードで綺麗に表現したい時

Qdrantを使う時

  • 5M件以上のベクター、または近い将来その規模が予想される時
  • 水平スケーリングと量子化でメモリコストを抑える必要がある時
  • ペイロードインデックスによる大規模メタデータフィルタがクリティカルパスにある時

Qdrantを避ける時

  • データが10万件以下と確実で、Docker運用の負担を背負う理由がない時。小規模のフィルタクエリはむしろChromaDBの方が速かった。
  • 一日で終わるハッカソンや使い捨てデモのように、導入の手間そのものがコストになる場面

pgvectorを使う時

  • すでにPostgreSQLを運用中でDBAがおり、追加インフラを0に保ちたい時
  • ベクター検索をユーザーや権限テーブルとJOINする必要がある時。これはChromaDBやQdrantでは表現が難しい。

pgvectorを避ける時

  • PostgreSQLが別サーバーにあり、クエリごとに10〜50msのネットワーク往復がクリティカルパスに加わる時
  • HNSWパラメータ(mef_constructionef_search)をチューニングするPostgreSQLの専門知識がチームにない時

公式ドキュメントと一次情報源

この記事の数値は直接測定した結果だが、インストール・API・インデックスパラメータは各プロジェクトの公式ドキュメントを一次情報源として確認するのが正確だ。

特にpgvectorは0.8.x系でhalfvec(2バイトfloat)、sparsevec、バイナリ量子化などのメモリ削減機能が追加された。high-dimの埋め込みを扱うなら、上記リリースノートを先に確認するとよい。

結局、私は何を使うのか

正直に言うと、2026年時点で私は新しいプロジェクトでQdrantをデフォルトとして使っている。理由はシンプルだ。小規模で多少のオーバーヘッドを許容しても、後でスケールが大きくなったときにマイグレーションするコストの方が大きい。

ただし、すでにPostgreSQLを運用しているチームならpgvectorをまず試すのが正解だ。大抵の場合それで十分で、後で性能が問題になったときにQdrantへ移行する戦略も現実的だ。

ChromaDBはプロトタイプでは依然1番手だ。pip install chromadb一行で始められる手軽さは圧倒的だ。ただしプロダクション移行のタイミングでは、Qdrantを真剣に検討すべきだ。

ベクターDBを選んだ次のステップは、それを包むAIエージェントライブラリの選択だ。Python AIエージェントライブラリ比較ガイドでその判断を続けることができる。

結局「どのDBが最高か」は意味のない質問だ。自分のスケール、チームの能力、既存インフラ、そしてどれだけ早く始める必要があるかによって答えが変わる。この記事の数字がその判断に具体的な根拠を一つ追加できれば十分だ。

よくある質問

Qdrant・ChromaDB・pgvectorのどれを選ぶべきか?
プロトタイプや数十万件以下の小規模ではインストールが簡単なChromaDBが向き、500万件以上の大規模や水平スケールが予想されるならQdrantが有利だ。すでにPostgreSQLを運用中なら追加インフラのないpgvectorをまず試すのが現実的だ。
pgvectorはいつ十分か?
すでにPostgreSQLインフラとDBAがあり、ベクター検索を既存のSQLクエリやJOINと組み合わせる必要があるときに最も適する。大抵の場合それで十分で、後で性能が問題になればQdrantへ移行する戦略も可能だ。
プロダクションでの性能差はどのくらいか?
1000ベクターの実測ではフィルタークエリがChromaDB 2ms、Qdrant 7msで小規模ではChromaDBが速く、挿入はQdrantが0.163sで速かった。ただし500万件以上の規模ではQdrantのHNSW最適化が優位になり、結果は逆転する。
小規模なのになぜQdrantはChromaDBより遅いのか?
Qdrantはペイロードインデックス、分散フィルタ、セグメント管理など大規模向けの構造を持つため、1000件のような小規模ではこの精巧さがむしろオーバーヘッドになる。ChromaDBは小規模でより直接的な方法でフィルタを処理するため速い。

他の言語で読む

この記事は役に立ちましたか?

より良いコンテンツを作成するための力になります。コーヒー一杯で応援してください。

著者について

jw

Kim Jangwook

AI/LLM専門フルスタック開発者

10年以上のWeb開発経験を活かし、AIエージェントシステム、LLMアプリケーション、自動化ソリューションを構築しています。Claude Code、MCP、RAGシステムの実践的な知見を共有します。

ブログリストへ