pgvector HNSW 索引
pgvector 提供的 HNSW 是图索引:用 hnsw 访问方法建索引,按向量类型与距离选择对应的算子类(如 vector_cosine_ops)。查询时用 hnsw.ef_search 调整候选队列长度,值越大召回越高、耗时越长;这个参数是会话级或语句级设置,不必重建索引。索引支持增量维护,新增向量会自动进入图结构,因此适合持续写入的业务库。前提是 ORDER BY 里用的算子必须与索引算子类匹配,否则规划器不会走索引。
基本信息
| 访问方法 | USING hnsw (列 算子类) |
|---|---|
| 算子类 | vector_cosine_ops、vector_l2_ops、vector_ip_ops |
| 构建参数 | m(默认 16)、ef_construction(默认 64) |
| 查询参数 | hnsw.ef_search,会话级或语句级设置 |
| 维护方式 | 支持增量写入,重建用 REINDEX |
典型使用场景
- 内部知识库检索:向量与业务表同库,过滤条件用普通 WHERE 表达
- 持续写入场景:新文档随时入库,索引自动维护
- 参数调优:按评测集在 ef_search 的若干档位上对比召回与延迟
- 灰度切换:新建索引后切算子,验证无误再清理旧索引
- 性能排查:用 EXPLAIN 确认查询确实走了向量索引而非全表扫描
建 HNSW 索引
建 HNSW 索引
CREATE INDEX CONCURRENTLY idx_kb_embedding ON kb_chunks
USING hnsw (embedding vector_cosine_ops)
WITH (m = 16, ef_construction = 200);
-- m:每层连接数(默认 16)
-- ef_construction:构建候选队列(默认 64),越大构建越慢质量越好查询期参数与验证
查询期参数与验证
SET hnsw.ef_search = 100; -- 会话级,越大召回越高
SELECT id FROM kb_chunks ORDER BY embedding <=> $1 LIMIT 10;
EXPLAIN ANALYZE -- 确认走的是向量索引
SELECT id FROM kb_chunks ORDER BY embedding <=> $1 LIMIT 10;参数取舍
| 参数 | 调大 | 代价 |
|---|---|---|
| m | 召回更高、查询更快 | 索引体积与构建时间上升 |
| ef_construction | 图质量更高 | 构建时间明显变长 |
| ef_search | 查询召回更高 | 单次查询延迟上升 |
| maintenance_work_mem | 构建更快 | 占用数据库内存 |
运维与调优要点
- 计划核对:EXPLAIN 确认命中向量索引,避免退化成顺序扫描
- 参数分层:m 与 ef_construction 影响索引质量,ef_search 只在查询期生效
- 构建窗口:大表建索引安排在低峰,临时提高 maintenance_work_mem
- 回退准备:保留旧索引与切换脚本,重建耗时超标时可快速回到原状
建索引前可临时提高 maintenance_work_mem 加快构建,并安排在低峰期执行;大表建索引用 CONCURRENTLY 避免长时间阻塞写入,但耗时更长。