· 王思腾 · 大模型工程 · 9 分钟阅读
向量数据库原理:海量 Embedding 如何被毫秒检索
RAG、语义搜索、推荐都依赖“给一个向量,找出最相似的 N 个向量”。百万到十亿级向量下,暴力比对不现实。本文从向量相似度讲起,聊 ANN 近似最近邻索引(IVF、HNSW、PQ 量化)、元数据过滤与混合检索,以及 Milvus、pgvector、Qdrant 该怎么选。

上一篇讲了 RAG:文档被嵌入模型转成向量后存入“向量数据库”,查询时再做相似度检索。那么问题来了——当成百上千万、甚至上亿个高维向量摆在那里,如何在几毫秒内找出最相似的 Top-K? 这就是向量数据库要解决的核心问题。
一、从“精确匹配”到“相似度匹配”
传统数据库查的是“等于/包含”(WHERE name = '张三'),而向量检索查的是“语义上最接近”。
文本经 embedding 模型变成一个高维向量(如 1536 维浮点数组),语义相近的文本在向量空间中距离更近。常用三种距离/相似度度量:
- 余弦相似度(Cosine):衡量方向夹角,最常用于文本语义,忽略向量长度;
- 点积(Dot Product / 内积):兼顾方向与模长;
- 欧氏距离(L2):直线距离。
检索目标:给定查询向量 q,从向量集合中找出距离最近/相似度最高的 K 个(KNN,K 近邻)。
二、暴力检索为什么不够
最朴素的方法是暴力检索(Flat / 精确 KNN):把查询向量和库中每个向量逐一算距离,排序取前 K。
- 优点:100% 精确,实现简单;
- 缺点:计算量随数据量线性增长。100 万条 1536 维向量,单次查询就是上亿次浮点运算——延迟和成本都扛不住。
因此生产环境用 ANN(Approximate Nearest Neighbor,近似最近邻):以牺牲一点点召回率为代价,换取数量级的加速。核心思想是“别全扫,用索引快速缩小搜索范围”。
三、主流 ANN 索引算法
1. IVF(倒排文件索引 / 聚类分桶)
先用聚类(如 k-means)把向量空间分成若干簇(nlist):
- 建索引:每个向量归入最近的簇中心;
- 查询:只在离查询点最近的若干簇(nprobe)里搜索,跳过大部分数据。
flowchart LR
Q["查询 q"] --> F["定位最近的 nprobe 个簇"]
F --> CA["簇 A"]
F --> CB["簇 B"]
F --> CC["簇 C"]
CA -. 仅在近邻簇内搜索 .-> R["Top-K 结果"]
CB -.-> R
CC -.-> R调 nprobe:越大越准但越慢,越小越快但可能漏。常与量化结合成 IVFFlat / IVF-PQ。
2. HNSW(分层可导航小世界图)——当前主流
HNSW(Hierarchical Navigable Small World)是目前效果与性能最均衡、应用最广的索引。它构建一个多层图:
- 上层节点稀疏、边长,用于快速“跳跃”接近目标区域;
- 下层节点密集、边短,用于精细查找。
- 检索时从最上层入口开始,贪心地走向更近的邻居,层层下钻,直到最底层找到最近邻。
flowchart TB
subgraph Top["上层:稀疏、长距离跳转"]
H1["A"] -.- H2["E"]
end
subgraph Mid["中层"]
M1["B"] -.- M2["C"] -.- M3["D"]
end
subgraph Bot["下层:稠密、精细查找"]
B1["···"] -.- B2["大量互连节点"] -.- B3["···"]
end
Entry["查询入口"] --> H1
H1 --> M2
M2 --> B2
B2 --> Out["最近邻"]- 优点:高召回 + 低延迟,查询极快;
- 代价:内存占用大(要存图结构)、构建较慢;
- 关键参数:
M(每个节点连边数)、efConstruction(建图质量)、efSearch(搜索广度,越大越准越慢)。
3. PQ(乘积量化)——压缩内存
高维向量很吃内存。PQ(Product Quantization)把向量切成若干子段,每段独立做聚类量化,用一个短编码代替原始浮点向量,大幅压缩(可达几十倍)。
- 优点:内存友好,能把更大数据集放进内存/SSD;
- 代价:有损,精度下降;
- 常组合为 IVF-PQ:先分簇、再量化,兼顾速度、内存与召回。
算法对比
| 索引 | 思路 | 速度 | 召回 | 内存 | 适用 |
|---|---|---|---|---|---|
| Flat | 全量暴力 | 慢 | 100% | 高 | 小数据/基线评测 |
| IVF | 聚类分桶 | 快 | 可调 | 中 | 大规模、成本敏感 |
| HNSW | 多层近邻图 | 很快 | 高 | 高 | 追求低延迟高召回 |
| IVF-PQ | 分桶+量化 | 很快 | 中 | 低 | 超大规模、内存受限 |
工程上常用“召回率-延迟-成本”三角做权衡,并通过 recall@K 评测调参。
四、向量数据库不只是“存向量”
一个生产可用的向量数据库还提供:
- CRUD 与动态更新:支持实时增删改,而不只是静态建库;
- 元数据过滤(Filtering):检索时按标签过滤,如“只在本部门、且近一年的文档里找”——通常用“先过滤后检索(pre-filter)”保证正确性;
- 混合检索(Hybrid Search):向量(语义)+ 全文/关键词(BM25)双路召回再融合(RRF 等),这对 RAG 尤其重要;
- 分片与副本:水平扩展支撑亿级向量与高并发;
- 持久化与备份:内存索引 + 磁盘持久化,重启可恢复。
五、常见产品与选型
| 类型 | 代表 | 特点 |
|---|---|---|
| 专用向量库 | Milvus | 开源、分布式、超大规模、生态完善 |
| Qdrant | Rust 写的,性能强、过滤能力好、轻量 | |
| Weaviate | 内置模块化(embedding/混合检索) | |
| 云托管 | Pinecone | 全托管免运维,按用量付费 |
| 数据库扩展 | pgvector | PostgreSQL 插件,向量与业务数据同库、事务/过滤方便 |
| 搜索引擎 | Elasticsearch/OpenSearch kNN | 向量+全文一体,适合已有 ES 栈 |
| 库 | Faiss(Meta) | 底层 ANN 库,无服务化,适合自研 |
选型思路:
- 数据量小、已在用 PostgreSQL →
pgvector最省事,一个库搞定; - 亿级向量、高并发、需要独立扩展 → Milvus / Qdrant;
- 不想运维、快速上线 → Pinecone 等托管服务;
- 重度依赖全文+语义混合 → ES/OpenSearch 或支持混合检索的专用库。
六、如何评估
- Recall@K:检索返回的 Top-K 里,命中了多少“真实相关”结果(和 Flat 精确结果对比);
- QPS / 延迟 P99:并发下的吞吐与响应时间;
- 内存与构建时间:索引占用、增量插入/更新开销;
- 端到端 RAG 效果:向量库只是一环,最终要看检索命中率和答案质量。
七、小结
- 向量检索的本质是“找语义最近的 K 个邻居”,用余弦/点积/L2 度量;
- 暴力检索精确但不可扩展,生产靠 ANN:IVF 分桶、HNSW 图(主流)、PQ 压缩;
- 向量数据库还要解决元数据过滤、混合检索、分布式扩展;
- 选型按数据规模、运维成本、是否要混合检索决定,小规模
pgvector往往足够。
下一篇我们换个角度,聊聊大模型应用的另一大成本瓶颈——LLM 推理优化:为什么生成那么慢、那么贵,以及工程上如何提速降本。
本文由 AI 辅助创作,所有内容仅供交流与参考。


