为什么需要专用向量数据库
既然向量只是数组,能不能直接存在 PostgreSQL 或 Redis 里?理论上可以,但向量检索的核心需求是近似最近邻搜索(ANN,Approximate Nearest Neighbor),这是一个高度特殊的计算问题:
- 暴力搜索(Brute-Force):对每个查询向量遍历所有存储向量计算相似度。百万级以下凑合,千万级以上延迟无法接受
- 传统 B-Tree 索引对高维向量完全无效——维度诅咒使得空间分割失去意义
- 专用向量数据库内置 HNSW、IVF 等 ANN 算法,可以在精度和速度之间取得最佳平衡
ANN
近似最近邻搜索(Approximate Nearest Neighbor)。不寻找精确的最近邻,而是用概率方法找"足够近"的邻居,以极大幅度降低计算量。对 RAG 来说,ANN 的近似误差完全可以接受。
HNSW
Hierarchical Navigable Small World,分层可导航小世界图。目前性能最优的 ANN 算法,通过构建多层级的图结构实现快速导航。是大多数向量数据库的默认索引。
IVF
Inverted File Index,倒排文件索引。将向量空间通过 K-means 聚类分成多个"桶",查询时只搜索最近的几个桶,大幅减少计算量。内存占用比 HNSW 小,适合超大规模数据集。
PQ(Product Quantization)
乘积量化。将高维向量分段压缩,大幅减少存储空间(通常压缩 32x)。通常与 IVF 组合使用(IVF-PQ),在亿级数据集上实现可接受的内存占用。
Recall@K
精确Top-K中被ANN算法正确找到的比例。Recall@10=0.95 意味着 ANN 找到的 Top-10 结果中,95% 与暴力搜索的精确 Top-10 一致。评估 ANN 质量的核心指标。
HNSW 索引原理详解
HNSW(2016 年 Yury Malkov 提出)是目前最广泛使用的 ANN 算法。它的核心思想借鉴了跳表(Skip List)和"六度分隔理论":
- 分层结构:图分多层,高层稀疏(长程连接),低层密集(精细搜索)
- 贪心导航:从高层入口节点出发,贪心地向目标移动,逐层下降直到最底层
- 小世界特性:任意两点之间通过很少的跳数可达,保证搜索效率
Layer 2 (最稀疏): A ───────────────── B
| |
Layer 1 (中间层): A ──── C ─── D ─── B
| | | |
Layer 0 (最密集): A─B─C─D─E─F─G─H─I─J─B
↑ 查询向量最近邻
HNSW 的两个关键超参数:
M:每个节点的最大连接数,越大精度越高但内存越多(通常 16–64)ef_construction:索引构建时的搜索宽度,越大精度越高但构建越慢(通常 100–500)ef_search:查询时的搜索宽度,可动态调整以权衡精度和速度
主流向量数据库横向对比
| 数据库 | 语言 | 部署方式 | 索引算法 | 特色功能 | 适合场景 |
|---|---|---|---|---|---|
| Qdrant | Rust | 自托管 / 云 | HNSW | 稀疏+稠密混合检索、载荷过滤、量化 | 生产首选,性能与功能最均衡 |
| Chroma | Python | 内嵌 / 自托管 | HNSW (hnswlib) | 零配置、LangChain 原生集成 | 原型开发、中小规模本地部署 |
| Pinecone | — | 全托管云服务 | 专有 | Serverless、命名空间多租户 | 不想运维、快速上线 |
| Weaviate | Go | 自托管 / 云 | HNSW + FLAT | GraphQL API、内置模块(BM25/神经搜索) | 需要 GraphQL 查询、多模态 |
| Milvus | C++ | 自托管 / Zilliz | HNSW/IVF/DiskANN | 分布式、GPU 加速、超大规模 | 十亿级向量、企业级分布式 |
| pgvector | C | PostgreSQL 插件 | HNSW / IVFFlat | SQL 查询、与现有 PG 集成 | 已有 PostgreSQL 架构的项目 |
深入了解各数据库
Qdrant:生产环境首选
用 Rust 编写,以性能、可靠性和丰富功能著称。是 2024-2025 年 RAG 生产项目中使用率最高的向量数据库。
核心优势
- Rust 实现:极低内存占用,零 GC 暂停
- 原生支持稀疏向量(用于 BM25 混合检索)
- 强大的载荷过滤:索引前过滤(pre-filtering)效率高
- 向量量化(Scalar / Product / Binary)大幅降低内存
- 分布式架构,支持分片和副本
适用场景
- 企业级 RAG 系统
- 需要精确过滤(按部门/权限/时间)
- 混合检索(稠密+稀疏)
- 内存受限但数据量大
- 需要自托管以满足数据合规
Chroma:原型开发神器
纯 Python 实现,嵌入式运行(无需独立服务器),与 LangChain/LlamaIndex 深度集成。
# pip install chromadb
import chromadb
# 内嵌模式:数据存本地文件
client = chromadb.PersistentClient(path="./chroma_db")
# 创建 Collection(类似向量库的表)
collection = client.get_or_create_collection(
name="knowledge_base",
metadata={"hnsw:space": "cosine"} # 余弦相似度
)
# 添加文档(Chroma 可以自动调用 Embedding)
collection.add(
documents=["RAG 的完整流程包括检索和生成", "向量数据库存储高维向量"],
ids=["doc_1", "doc_2"],
metadatas=[{"source": "ch1"}, {"source": "ch4"}]
)
# 查询
results = collection.query(
query_texts=["RAG 怎么运作?"],
n_results=2
)
print(results['documents'])
Pinecone:全托管无运维
完全托管的向量数据库服务,Serverless 模式下按使用量计费,适合快速上线的创业项目。
- 免运维:不需要配置、扩容、备份
- Serverless:索引存储和计算分离,低频使用成本极低
- 命名空间(Namespace):天然支持多租户
- 缺点:数据托管在美国服务器,数据合规要求高的场景不适用
Milvus:超大规模向量检索
专为十亿级向量设计的分布式向量数据库,支持 GPU 加速,是目前开源中规模最大的向量数据库系统。
Milvus 的运维成本
Milvus 依赖 etcd(元数据)+ MinIO(对象存储)+ Pulsar(消息队列),启动一套完整集群需要较多资源。如果数据量在千万以下,Qdrant 的运维复杂度远低于 Milvus,建议优先考虑。
选型决策树
开始选型
│
├─ 只需快速原型? → Chroma(内嵌,零配置)
│
├─ 不想运维,接受数据在云端? → Pinecone Serverless
│
├─ 数据必须自托管(合规要求)?
│ │
│ ├─ 规模 < 1000万向量 → Qdrant(推荐)
│ │
│ ├─ 规模 1000万~10亿 → Qdrant 集群 或 Milvus
│ │
│ └─ 规模 > 10亿 → Milvus + GPU
│
├─ 已有 PostgreSQL,不想引入新组件? → pgvector
│
└─ 需要 GraphQL + 多模态 → Weaviate
关键性能指标对比
以下数据来自 ANN Benchmarks(ann-benchmarks.com),测试集:SIFT-1M(100万 128维浮点向量):
| 指标 | Qdrant HNSW | Milvus HNSW | pgvector HNSW | Chroma |
|---|---|---|---|---|
| QPS(查询/秒) | ~12,000 | ~10,000 | ~3,000 | ~2,000 |
| Recall@10 | 0.98 | 0.97 | 0.97 | 0.97 |
| 内存占用 | 低(量化后) | 中 | 中 | 中 |
| P99 延迟 | < 5ms | < 8ms | < 20ms | < 15ms |
性能测试的真实含义
实际 RAG 场景中,向量检索通常只占总响应时间的 5–20%,LLM 生成(1–10秒)才是瓶颈。选型时不要过分纠结 QPS,更应关注功能完整性、运维难度和团队熟悉度。
本章总结
- 向量数据库的核心价值:内置 ANN 算法(HNSW/IVF),让亿级向量检索毫秒级响应
- HNSW:层次化图结构,精度高,适合实时检索;IVF+PQ:内存占用小,适合超大规模
- 选型建议:原型用 Chroma,生产优先 Qdrant,超大规模用 Milvus,不想运维用 Pinecone
- 向量检索不是 RAG 性能瓶颈,LLM 生成才是——不要过度优化检索层