揭秘pgvector检索:HNSW与IVFFlat优劣解析
目录
结论
pgvector 检索的本质:把文本、图片等内容先转成 embedding 向量,存进 PostgreSQL;查询时也把 query 转成向量,然后找数据库里和 query 向量“距离最近”的记录。
1. 基本原理
例如你有一段文档:
新能源汽车产业链包括电池、电机、电控、充电设施等环节。
embedding 模型会把它转成类似这样的高维向量:
[0.12, -0.08, 0.33, ..., 0.41]
用户问题:
动力电池产业包括哪些环节?
也会被转成向量。
pgvector 做的事情就是:
query embedding
↓
和数据库里的 document embedding 计算距离
↓
返回距离最近的 top-k chunk
2. 常见相似度计算
pgvector 支持多种距离/相似度操作,常见的是:
| 类型 | 含义 | 常用场景 |
|---|---|---|
| Cosine distance | 看两个向量方向是否接近 | 文本语义检索最常用 |
| L2 distance | 欧氏距离,看空间距离 | 图像、通用向量检索 |
| Inner product | 内积,值越大越相似 | 某些 embedding 模型推荐 |
RAG 文本检索里,通常优先用:
ORDER BY embedding <=> query_embedding
LIMIT 10;
其中:
<=>
一般表示 cosine distance。pgvector 文档列出了 L2、inner product、cosine、L1、Hamming、Jaccard 等距离操作符。(GitHub)
3. 不建索引时:暴力检索
最朴素的方式是:
SELECT *
FROM chunks
ORDER BY embedding <=> '[0.1, 0.2, ...]'::vector
LIMIT 10;
它会把 query 向量和表里所有向量逐个比较。
优点:
-
结果准确;
-
实现简单;
-
小数据量够用。
缺点:
-
数据一大就慢;
-
每次都要扫很多行。
所以才需要向量索引。
4. HNSW 原理
HNSW 可以理解成“向量近邻图”。
它会把相似的向量连成图:
A —— B —— C
| |
D —— E —— F
查询时不是全表扫描,而是:
从一个入口点开始
↓
沿着“越来越接近 query 的邻居”不断跳转
↓
快速找到附近的一批候选
↓
返回 top-k
它的核心特点:
| 特点 | 说明 |
|---|---|
| 查询快 | 通常召回率和速度都比较好 |
| 召回高 | RAG 场景常用 |
| 构建慢 | 建索引成本更高 |
| 占内存较多 | 比 IVFFlat 更吃资源 |
| 不要求先有数据再建 | 可以在空表上创建索引 |
pgvector 官方也说明:HNSW 的查询性能在速度和召回的 trade-off 上通常更好,但构建更慢、占用内存更多。(GitHub)
5. IVFFlat 原理
IVFFlat 可以理解成“先聚类,再只搜相关簇”。
它会先把所有向量分成很多 lists / clusters:
cluster 1: A, B, C
cluster 2: D, E, F
cluster 3: G, H, I
查询时:
query embedding
↓
先判断 query 离哪些 cluster 最近
↓
只搜索这些 cluster 里的向量
↓
返回 top-k
所以它不是搜全库,而是搜一部分候选集合。
特点:
| 特点 | 说明 |
|---|---|
| 构建快 | 比 HNSW 快 |
| 内存更省 | 成本较低 |
| 查询性能一般 | 速度/召回 trade-off 通常不如 HNSW |
| 需要已有数据 | 最好在表里已有代表性数据后再建索引 |
| 参数敏感 | lists、probes 会明显影响召回 |
pgvector 官方说明:IVFFlat 会把向量分成 lists,然后搜索最接近查询向量的一部分 lists;它构建更快、内存更少,但查询性能通常低于 HNSW。(GitHub)
6. HNSW vs IVFFlat 怎么选
推荐默认选 HNSW
对于你的 RAG 场景:
PostgreSQL + pgvector + BM25 + reranker
我建议默认用:
CREATE INDEX ON chunks
USING hnsw (embedding vector_cosine_ops);
原因:
-
检索质量更稳;
-
不太依赖聚类参数;
-
适合持续写入;
-
RAG 更怕漏召回,不只是怕慢。
IVFFlat 适合什么情况?
IVFFlat 更适合:
-
数据量较大;
-
内存比较紧;
-
索引构建速度很重要;
-
数据相对稳定;
-
你愿意调
lists和probes。
7. 一句话总结
pgvector = 在 PostgreSQL 里存 embedding,并按向量距离找最相似内容。
HNSW = 建一张近邻图,沿图快速找相似向量。
IVFFlat = 先把向量聚类,查询时只搜最相关的几个簇。
你的 RAG 项目里,优先 HNSW;数据特别大或资源紧张时再考虑 IVFFlat。
更多推荐


所有评论(0)