DEBUG.WIKI
京东云;让 AI 进入真实业务;零售 · 物流 · 客服 · 硬件;查看方案 →
ZgoCloud:多地区部署,按需选节点;日本、美国、香港、德国
Evoxt;最高 6.0GHz CPU;高频云服务器 · 免费每周备份;查看配置 →

pgvector 余弦查询建了索引仍走 Seq Scan,检查 ORDER BY 是否直接用距离

相似度可在 SELECT 中计算,索引排序需要直接按距离算子升序并 LIMIT。对照 SQL、operator class 和计划,再按负载测量;小表 Seq Scan 未必是错误。

余弦查询算出了正确相似度,却没有使用已经建好的 HNSW 索引。常见写法是:

ORDER BY 1 - (embedding <=> '[0.2,0.1,0.3]'::vector) DESC

业务上这是“相似度从高到低”,但索引访问方式需要识别直接的距离排序。pgvector 0.8.0 的排障说明明确要求 ORDER BY 是距离算子的升序结果,并且有 LIMIT。这是一类查询形状问题,没有固定异常文本。

展示相似度,排序仍用距离

假定 items.embedding 是三维向量,且已有对应余弦索引,可以改为:

SELECT id,
       1 - (embedding <=> '[0.2,0.1,0.3]'::vector) AS similarity
FROM items
ORDER BY embedding <=> '[0.2,0.1,0.3]'::vector
LIMIT 10;

这保留展示字段,仅把排序表达式恢复为索引支持的形式。真实向量需要与列维度、embedding 模型一致,示例三个数字不代表可用的语义查询向量。

再核对索引定义:

SELECT indexname, indexdef
FROM pg_indexes
WHERE schemaname = 'public' AND tablename = 'items';

<=> 的余弦查询应与相应的 vector_cosine_ops 配对;L2、内积或表达式索引不是看到同一列就能替代。列是 halfvec、二进制或子向量表达式时,另按实际索引契约核对。

计划变了,还要测实际负载

先用 EXPLAIN 比较修改前后的查询;允许执行负载测试时,再使用 EXPLAIN (ANALYZE, BUFFERS),它会真正运行查询。保留过滤条件、同一向量和同一 LIMIT,避免比较两个不同业务请求。PostgreSQL 的 EXPLAIN 说明区分了计划估计与实际运行。

小表或高匹配率查询,规划器可能认为顺序扫描更便宜。满足索引语法并不强制选择索引,Seq Scan 也不自动等于故障。查看统计信息、行数、过滤选择性和实际耗时后,再判断是否需要更多优化。

不要全局关闭 enable_seqscan 强迫所有查询走索引,更不能把删除过滤条件当作优化。这里也不要求在唯一生产表上临时重建索引来验证一行 SQL。

最终检查输出数量、排序和耗时达到业务要求。HNSW 属于近似搜索,修改前的顺序扫描可能提供精确结果;切换索引后应对照固定测试集的召回。只看到 Index Scan,不能证明检索质量也已通过。