向量数据库并非都解决相同的问题
自2023年RAG热潮以来,向量数据库市场已经相当集中。Pinecone、Weaviate、Qdrant和pgvector现在是部署最普遍的四种解决方案,但它们代表了真正不同的架构权衡——不仅仅是价格不同。为你的工作负载选择错误的解决方案,代价不仅仅是金钱:还包括你在发布后花费数月时间才发现性能假设是错误的成本。本指南通过具体的基准测试、配置示例和基于实际区分这些解决方案工作负载特征的决策框架,对这四个选项进行了比较。
向量数据库的实际功能
向量数据库存储高维数值向量(嵌入)并回答近似最近邻(ANN)查询:给定一个查询向量,在数据库中找到K个最相似的向量。”近似”部分很重要——在数百万个向量中进行精确最近邻搜索在计算上是不可行的,因此所有生产级向量数据库都使用ANN算法,以牺牲少量召回率为代价,换取数量级的速度提升。
这些数据库使用的核心ANN算法:
- HNSW(分层可导航小世界): 一种基于图的索引,通过导航多层邻近图来高效找到近似邻居。出色的查询速度,高内存使用,快速插入/更新。Qdrant、Weaviate和pgvector使用此算法。
- IVF(倒排文件索引): 将向量空间划分为簇(Voronoi单元),并在查询时只搜索最近的簇。内存使用低于HNSW,查询速度稍慢,更适合不常变化的数据集。Pinecone和pgvector使用此算法。
- DiskANN: Qdrant的基于磁盘的索引,用于内存无法容纳的超大数据集。显著降低内存需求,同时适度牺牲查询速度。
pgvector:当你已经拥有PostgreSQL时
pgvector 是一个 PostgreSQL 扩展,为您的现有数据库添加了向量存储和相似性搜索功能。它不是一个专门的向量数据库——而是将向量搜索集成到关系型数据库中。在决定何时使用它时,这一区别至关重要。
-- 安装并启用 pgvector
CREATE EXTENSION IF NOT EXISTS vector;
-- 创建一个包含向量列的表
-- 1536 维度 = OpenAI text-embedding-3-small 输出
CREATE TABLE documents (
id BIGSERIAL PRIMARY KEY,
content TEXT NOT NULL,
metadata JSONB NOT NULL DEFAULT '{}',
embedding vector(1536),
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
-- 创建 HNSW 索引用于近似最近邻搜索
-- m: 每个节点的连接数(越高=召回率越好,内存占用越多)
-- ef_construction: 构建过程中的候选列表大小(越高=索引质量越好)
CREATE INDEX documents_embedding_hnsw_idx ON documents
USING hnsw (embedding vector_cosine_ops)
WITH (m = 16, ef_construction = 64);
-- 查询:查找与查询向量最相似的 10 个文档
-- 将 '[0.1, 0.2, ...]' 替换为您嵌入模型中的实际向量
SELECT
id,
content,
metadata,
1 - (embedding <=> '[0.1, 0.2, 0.3]'::vector) AS cosine_similarity
FROM documents
WHERE metadata->>'category' = 'technical' -- 与标准 SQL 过滤器结合
ORDER BY embedding <=> '[0.1, 0.2, 0.3]'::vector
LIMIT 10;
pgvector 的关键优势在于您的向量数据与关系型数据位于同一数据库中。您可以在单个查询中进行过滤、连接和聚合,无需跨系统协调。关键限制是,在普通硬件上,pgvector 无法扩展到 Pinecone 级别的查询量或数据集大小——数百万向量的 HNSW 索引需要大量内存,当过滤器具有选择性时,PostgreSQL 的查询规划器并不总是能高效地选择向量索引。
何时使用 pgvector:您的数据集少于 500 万个向量,您已经在运行 PostgreSQL,您需要频繁将向量搜索结果与关系型数据连接,并且您没有高并发的相似性查询需求。
Qdrant:专为生产性能而构建
Qdrant 是一个用 Rust 编写的开源向量数据库,专为在生产环境中进行高性能相似性搜索而设计。它支持 HNSW 和自己的 DiskANN 实现,提供量化功能以减少内存使用,并拥有丰富的过滤系统,能够在 ANN 搜索过程中(而非之后)高效应用过滤器。
from qdrant_client import QdrantClient
from qdrant_client.models import (
Distance, VectorParams, PointStruct,
Filter, FieldCondition, MatchValue, Range
)
client = QdrantClient(host="localhost", port=6333)
# 创建带有 HNSW 配置的集合
client.create_collection(
collection_name="tech_articles",
vectors_config=VectorParams(
size=1536,
distance=Distance.COSINE,
hnsw_config={
"m": 16,
"ef_construct": 100,
"full_scan_threshold": 10_000
},
# 标量量化:将向量从 float32 压缩到 int8
# 质量损失极小的情况下实现约 4 倍内存减少
quantization_config={
"scalar": {
"type": "int8",
"quantile": 0.99,
"always_ram": True # 将量化向量保留在 RAM 中
}
}
)
)
# 插入带有负载(元数据)的向量
client.upsert(
collection_name="tech_articles",
points=[
PointStruct(
id=1,
vector=[0.1, 0.2, ...], # 1536 维嵌入向量
payload={
"title": "Container Networking Deep Dive",
"category": "infrastructure",
"published_year": 2026,
"word_count": 2100
}
)
]
)
# 使用预过滤进行搜索(过滤器在 ANN 期间应用,而非之后)
# 这是 Qdrant 相比 pgvector 在过滤搜索方面的关键优势
results = client.search(
collection_name="tech_articles",
query_vector=[0.15, 0.25, ...],
query_filter=Filter(
must=[
FieldCondition(
key="category",
match=MatchValue(value="infrastructure")
),
FieldCondition(
key="published_year",
range=Range(gte=2025)
)
]
),
limit=10,
with_payload=True,
search_params={"hnsw_ef": 128} # 查询时增加以获得更好的召回率
)
Qdrant 的预过滤是一个有意义的技术差异化因素。当您在 ANN 搜索之后应用过滤器时,您会检索比实际需要更多的向量然后丢弃许多——这需要更大的初始搜索来保证找到足够的匹配结果。Qdrant 将过滤器构建到图遍历中,在不扩大搜索范围的情况下保持召回质量。
何时使用 Qdrant: 您需要一个专用的向量数据库,您有严格的内存预算(量化有帮助),您需要复杂的元数据过滤而不应牺牲召回率,并且您希望拥有可自托管的、具有强大生产工具的开源解决方案。
Weaviate: 带知识图层的向量搜索
Weaviate将自己定位为”AI原生数据库”,结合了向量搜索与类图的对象模型以及内置的ML模型集成。它可以在摄取数据时使用配置的向量化器(OpenAI、Cohere、Hugging Face transformers)自动将对象向量化,无需预先生成的嵌入向量。
import weaviate
from weaviate.classes.config import Configure, Property, DataType
from weaviate.classes.query import MetadataQuery
client = weaviate.connect_to_local()
# 创建带有自动向量化的集合
# Weaviate在摄取时调用嵌入模型 — 无需预嵌入
articles = client.collections.create(
name="TechArticle",
vectorizer_config=Configure.Vectorizer.text2vec_openai(
model="text-embedding-3-small"
),
properties=[
Property(name="title", data_type=DataType.TEXT),
Property(name="content", data_type=DataType.TEXT),
Property(name="category", data_type=DataType.TEXT),
Property(name="wordCount", data_type=DataType.INT),
]
)
# 插入 — Weaviate自动对'content'字段进行嵌入
articles.data.insert({
"title": "零信任架构实践",
"content": "参与任何企业安全对话...",
"category": "security",
"wordCount": 2100
})
# 语义搜索
results = articles.query.near_text(
query="容器网络 kubernetes",
limit=5,
filters=weaviate.classes.query.Filter.by_property("category").equal("infrastructure"),
return_metadata=MetadataQuery(distance=True, score=True)
)
for obj in results.objects:
print(f"{obj.properties['title']} — 距离: {obj.metadata.distance:.3f}")
Weaviate还支持混合搜索 — 在单个查询中结合向量相似性与BM25关键词搜索,并通过alpha参数进行加权。这对于语义相似性和关键词匹配都很重要的搜索应用非常有价值。
何时使用Weaviate: 您需要内置的嵌入模型集成(无需单独的嵌入管道),您需要混合向量+关键词搜索,或者您的用例受益于对象图模型及对象间的引用关系。
Pinecone: 无需运维开销的管理规模扩展
Pinecone 是一个完全托管的向量数据库即服务。无需管理基础设施,无需调整索引,也无需升级版本。代价是在大规模应用时的成本以及对底层实现缺乏控制。
from pinecone import Pinecone, ServerlessSpec
pc = Pinecone(api_key="YOUR_API_KEY")
# 创建无服务器索引(无需硬件配置)
pc.create_index(
name="tech-articles",
dimension=1536,
metric="cosine",
spec=ServerlessSpec(
cloud="aws",
region="us-east-1"
)
)
index = pc.Index("tech-articles")
# 向量与元数据批量插入
index.upsert(
vectors=[
{
"id": "article-001",
"values": [0.1, 0.2, ...], # 1536维嵌入向量
"metadata": {
"title": "零信任架构",
"category": "security",
"year": 2026
}
}
],
namespace="production"
)
# 查询
results = index.query(
vector=[0.15, 0.25, ...],
filter={"category": {"$eq": "security"}},
top_k=10,
include_metadata=True,
namespace="production"
)
Pinecone 的无服务器层级显著改善了其成本结构。旧的基于 Pod 的定价对小规模工作负载来说很昂贵;而无服务器定价每百万查询单元 0.10 美元,每向量每小时存储 0.000001 美元,对于中等规模工作负载具有竞争力。在极高的查询量(每天 1000 万次以上查询)情况下,经济性会发生变化,自托管 Qdrant 通常更具优势。
何时使用 Pinecone: 您希望零基础设施管理,您的团队没有能力运营向量数据库,您正在构建早期产品并希望推迟基础设施决策,或者您需要 Pinecone 的 SLA 和支持合同来满足企业需求。
性能比较
ann-benchmarks 项目提供了标准化基准,但生产性能很大程度上取决于您的特定工作负载。关键变量:向量维度、数据集大小、过滤选择性和硬件。基于在典型云硬件上对 100 万向量、1536 维数据集的常用报告基准:
- 查询延迟(p99): Qdrant 和 Pinecone 通常在无过滤查询中能达到低于 10ms 的延迟。在同等硬件上,pgvector 的 HNSW 查询运行时间为 20-50ms,使用 IVF-flat 时更慢。
- 内存效率: 使用 int8 标量量化的 Qdrant 比使用 float32 HNSW 索引的 pgvector 节省约 4 倍内存。在大规模应用中至关重要。
- 过滤查询性能: 在高过滤选择性下,Qdrant 的预过滤方法保持召回率,而 pgvector 的后过滤方法性能下降。
- 吞吐量: 对于持续的写入密集型工作负载,Qdrant 的 Rust 实现比 Weaviate 基于 JVM 的架构能处理更高的并发插入速率。
决策矩阵
- 小型数据集(<200万向量)+ 现有PostgreSQL + 复杂SQL连接: pgvector。在此规模下,操作简便性胜过性能差距。
- 中大型数据集 + 复杂元数据过滤 + 自托管: Qdrant。对于能够运行容器的团队,这是性能与运营成本的最佳比例。
- 需要内置嵌入管道 + 混合搜索: Weaviate。对于不想单独管理嵌入生成的团队,可降低管道复杂性。
- 托管、零运维、早期产品: Pinecone serverless。在专注于产品市场契合度的同时,为便利性付费。
关键要点
- 当您的数据集适合存储在PostgreSQL中,并且需要将向量搜索与关系查询结合时,pgvector是正确选择。它不是高性能向量数据库。
- Qdrant的预过滤架构在选择性元数据过滤器下保持召回质量——这是在规模上优于后过滤方法的重要优势。
- Weaviate的内置向量化器集成将嵌入管道从您的架构中移除,降低了复杂性,但代价是对嵌入过程的控制力减弱。
- Pinecone serverless在中等工作负载下具有竞争力,并且消除了所有基础设施管理——是早期产品或没有向量数据库运营专业团队的正确选择。
- 在高查询量(每天1000万+查询)下,自托管Qdrant通常比托管Pinecone具有更好的经济性。在假设托管更昂贵之前,请针对您的工作负载进行具体计算。
