先把当时的情况摆出来。同一批查询跑两次结果差异明显,有些明显相关的文档时有时无,索引已经建好也做了 vacuum。
把日志和配置对完,能解释这个现象的基本就这几处。ef_search 默认值偏小,候选集不足。还有一种是数据刚批量导入,索引还没完全生效。
不容易想到的是,过滤条件与向量检索叠加,候选被大幅削减。还有一种情况,查询向量与入库时的归一化方式不一致。
提高候选集大小再试
SET hnsw.ef_search = 100;
接着在会话级设置而不是全局改
SET LOCAL hnsw.ef_search = 100;
然后对过滤场景先过滤再检索
python -c "print('push filters into where clause')"
剩下的就是抽样对比两次查询结果的重合度
python eval_stability.py --q 100 --k 10
别只看报错消失,验证要多做一步。两次查询结果高度一致,召回稳定,延迟增加但仍在可接受范围内。
补一句。ef_search 只影响查询不影响索引,按请求动态调整比全局改更安全,高并发时记得评估额外开销。拖得越久,排查成本越高,因为现场状态会被后续操作覆盖。