pgvector 生产最佳实践
用 exact 基线、过滤后召回和可重建索引管理向量检索
pgvector 默认执行精确最近邻搜索;添加 HNSW 或 IVFFlat 索引后才进入近似搜索。索引选择是召回、延迟、内存、构建时间和写入成本之间的工程决策。
先固定距离语义
| 业务语义 | 操作符 | 索引 operator class |
|---|---|---|
| L2 / 欧氏距离 | <-> | vector_l2_ops |
| 内积(返回负内积) | <#> | vector_ip_ops |
| 余弦距离 | <=> | vector_cosine_ops |
embedding 生成、索引和查询必须使用同一种距离语义。余弦相似度是 1 - cosine distance。保存 embedding_model、维度、归一化方式和生成版本;不可比较的向量不要混入一个列/索引。
建立 exact 基线
从真实查询分布抽样并保存 exact top-k。评估近似索引时,比较 recall@k、p50/p95/p99 延迟、候选不足率和资源消耗,而不是只看单次速度。
BEGIN;
SET LOCAL enable_indexscan = off;
SELECT c.id
FROM document_chunks AS c
JOIN documents AS d ON d.id = c.document_id
WHERE d.tenant_id = $1
ORDER BY c.embedding <=> $2::vector
LIMIT 20;
ROLLBACK;禁用 index scan 只用于基线/诊断,不是生产查询设置。测试集要覆盖热门/冷门 tenant、常见 ACL、时间过滤、新写入、删除和 embedding 分布漂移。
HNSW 与 IVFFlat
CREATE INDEX CONCURRENTLY document_chunks_embedding_hnsw
ON document_chunks
USING hnsw (embedding vector_cosine_ops);- HNSW:通常查询性能与 speed/recall tradeoff 更好,不需要训练数据;构建慢、使用更多内存,索引维护成本也更高。
- IVFFlat:构建更快、内存更少;需要已有代表性数据来形成 lists,且 speed/recall tradeoff 通常低于 HNSW。不要在空表上创建后就忘记重建。
- 生产已有表优先
CREATE INDEX CONCURRENTLY,并在副本上观察 WAL、磁盘、构建时间和复制延迟。
没有适用于所有数据集的 m、ef_construction、ef_search、lists 或 probes 常数。先用默认值和 exact 基线,再用真实过滤条件调参。
过滤会改变召回
使用近似索引时,过滤条件通常在索引扫描产生候选后应用。默认 hnsw.ef_search = 40 时,如果只有 10% 候选满足 tenant/ACL 条件,结果可能少于 LIMIT,即使数据库里存在更多匹配行。
pgvector 0.8.0+ 支持 iterative scans,索引候选不足时继续扫描:
BEGIN;
SET LOCAL hnsw.iterative_scan = strict_order;
SET LOCAL hnsw.ef_search = 200;
SELECT c.id, c.content, c.embedding <=> $1::vector AS distance
FROM document_chunks AS c
JOIN documents AS d ON d.id = c.document_id
WHERE d.tenant_id = $2
AND d.access_scope && $3::text[]
ORDER BY c.embedding <=> $1::vector
LIMIT 20;
COMMIT;先确认云服务提供的 pgvector 版本。若 tenant 值较少且不均衡,可考虑 list partitioning;若值很多,可把高频 tenant 部分索引、独立表或物理隔离。选择必须用过滤后的 recall 与运维成本验证。
SQL 过滤安全,不保证 ANN 召回
tenant/ACL 条件必须留在 SQL/RLS 内,不能先取全局结果再由应用过滤。即使数据库正确阻止越权行,共享 ANN 图仍可能因后过滤返回不足;安全性和召回率是两个分别验证的目标。
上线门槛
- 每个 embedding 版本有可重放摄取、exact gold set 和回滚路径;
- 在线记录模型版本、过滤桶、候选数、结果数、距离分布、延迟和截断;
- 定期抽样 exact 查询计算 recall@k,并按 tenant/ACL 分桶;
- embedding 重建双写到新列/表,建新索引、评估后原子切流;
- 原文和 metadata 是事实来源,向量可以从版本化输入重建;
- 混合检索分别产生全文/向量候选,再以可版本化方法融合或重排。
官方参数与限制以 pgvector README 的索引、过滤和监控章节为准。
Last updated on