id, title, type, domain, stack, tags, level, prerequisites, est_hours, related, week, order
| id |
title |
type |
domain |
stack |
tags |
level |
prerequisites |
est_hours |
related |
week |
order |
| ai.vector-db.selection-pgvector |
向量库选型和 pgvector 实战:Chroma / pgvector / Milvus / Elasticsearch |
lesson |
ai |
|
| 向量库选型 |
| pgvector |
| Chroma |
| Milvus |
| Elasticsearch |
| 元数据过滤 |
|
intermediate |
|
3 |
| ai.vector-db.scenario.multi-tenant-index |
| backend.postgresql.index |
| backend.elasticsearch.index |
|
|
2 |
向量库选型和 pgvector 实战:Chroma / pgvector / Milvus / Elasticsearch
解释说明
选型对比
| 方案 |
适合 |
优点 |
注意 |
| Chroma |
原型、学习、小规模 |
安装即用,Python 内嵌模式 |
大规模、高可用要评估;版本间 API 有变化 |
| pgvector(PostgreSQL 扩展) |
已有 PostgreSQL、百万级以内、需要和业务数据联查 |
一套数据库;SQL 过滤、事务、备份都复用 |
超大规模和高 QPS 时不如专用向量库;向量索引的内存占用要规划 |
| Milvus |
千万到亿级、需要分布式 |
多种索引、分区、标量过滤、水平扩展 |
组件多,运维成本高(也有托管版) |
| Elasticsearch / OpenSearch |
已经用 ES 做全文检索,想要关键词 + 向量混合检索 |
一个引擎做 BM25 + kNN |
向量功能的版本差异较大,以官方文档为准 |
| FAISS |
嵌入到程序里的向量检索库 |
快,索引类型全 |
是库不是数据库:没有持久化服务、过滤、权限,需要自己做 |
本计划的选择:学习阶段用 Chroma 或 numpy 快速理解;项目使用 pgvector,因为第 3~4 周已经学了 PostgreSQL,业务数据、权限和向量可以放在同一个库里联查;面试时能讲清楚“为什么不用 Milvus”和“什么规模需要换”。
- 类型:
vector(n);还有 halfvec(半精度,省一半空间)、sparsevec。
- 运算符:
<-> L2 距离,<#> 负内积,<=> 余弦距离(都是越小越近)。
- 索引:
USING hnsw (embedding vector_cosine_ops),运算符类必须和查询用的运算符一致(vector_l2_ops / vector_ip_ops / vector_cosine_ops),否则不走索引。
- 查询参数:
SET hnsw.ef_search = 100;(默认 40);IVFFlat 用 ivfflat.probes。
- 过滤:
WHERE tenant_id = $1 ORDER BY embedding <=> $2 LIMIT 10。过滤条件很严格时,0.8 版本可以开启 hnsw.iterative_scan 让索引继续扫描直到凑够结果;或者按租户建部分索引 / 分区。
案例
一个 SaaS 客服系统,50 个租户共 200 万个知识块,平均每个租户 4 万,最大租户 60 万。业务表已经在 PostgreSQL 中。选择 pgvector:块表带 tenant_id,HNSW 索引 + tenant_id 普通索引;大租户检索结果不足时开启迭代扫描。评估结论写进文档:当总量超过数千万或 QPS 超过单机能力时,再评估 Milvus。
代码示例
pgvector 的表结构和查询(完整可运行版本 examples/vector-stores/pgvector_demo.py,已在 PostgreSQL 17 + pgvector 0.8.0 上运行):
Chroma 的写入、元数据过滤、更新删除见 examples/vector-stores/chroma_demo.py。
易错点
- 建索引用了
vector_l2_ops,查询用 <=>:不走索引,变成全表扫描。
<#> 返回的是负内积,排序时直接 ORDER BY embedding <#> q 就是内积从大到小;自己再加负号就反了。
- 小表的执行计划显示顺序扫描:数据少时规划器认为顺序扫描更便宜,这是正常的,不是索引失效。
- HNSW 索引默认不支持太高的维度(
vector 类型的索引上限 2000 维,halfvec 4000 维,以官方文档为准),高维模型要选 halfvec 或降维。
- 大批量导入时边写边维护 HNSW 索引很慢:先导入再建索引,并适当调大
maintenance_work_mem。
- Chroma 不同版本的客户端 / 持久化格式有变化,升级前看迁移说明。
面试常问
- 为什么选 pgvector 而不是 Milvus?什么时候要换?
- pgvector 的三种距离运算符分别是什么?索引怎么建才能生效?
- 向量和业务数据放一个库有什么好处和风险?