IVFFlat 在 pgvector 里
IVFFlat 按聚类把向量划分到若干列表(lists),查询时只扫描 ivfflat.probes 指定的列表数,从而减少距离计算次数。它要求建索引时表里已经有数据,否则聚类中心没有意义、召回明显偏低;数据量大幅增长后,聚类划分与实际分布失配,需要 REINDEX 重建索引才能恢复召回水平。
基本信息
| 建索引时机 | 表内已有代表性数据之后再建 |
|---|---|
| lists | 划分粒度,按行数规模选取 |
| probes | 查询扫描的列表数,属会话级参数 |
| 维护 | 数据大幅增长或分布变化后 REINDEX 重建 |
典型使用场景
- 已有 PostgreSQL 的团队:不引入新组件即可支撑十万级切片的检索
- 索引效果验证:对比建索引前后的召回与延迟,确认收益
- 参数调优:调 lists 与 probes 寻找召回与延迟的平衡点
- 与过滤条件配合:配合 WHERE 使用时要检查执行计划是否走索引
- 定期维护:把 REINDEX 纳入运维计划,避免召回随时间下降
建 IVFFlat 索引
建 IVFFlat 索引
-- 先导入数据再建索引,空表建索引会得到无意义的聚类中心
CREATE INDEX ON kb_chunks
USING ivfflat (embedding vector_cosine_ops)
WITH (lists = 100);
-- 查询期控制扫描列表数,值越大召回越高
SET ivfflat.probes = 10;
SELECT id FROM kb_chunks ORDER BY embedding <=> $1 LIMIT 10;
参数与经验起点
| 参数 | 经验起点 | 说明 |
|---|---|---|
| lists | 行数不超过一百万取行数除以千;超过则取行数平方根 | 列表过多会稀释每个列表的作用 |
| probes | 从 lists 的平方根附近开始 | 越大召回越高,延迟越高 |
| 距离操作符类 | 需与查询所用操作符匹配 | 不匹配时索引不会被选用 |
| REINDEX | 数据规模或分布明显变化后 | 否则召回逐步变差 |
索引是快照式的:数据大幅增长后应 REINDEX 重建,否则召回逐步变差;重建会占用额外磁盘与时间,要安排在不影响业务的窗口。
建索引后用 EXPLAIN 确认索引真正被使用:查询里带过滤条件时,优化器可能改走顺序扫描,索引白建且延迟更高,排查时先看执行计划再调参数。