HNSW 索引是什么
HNSW(分层可导航小世界图)是当前主流的近邻检索索引:靠多层图结构实现快速跳转,查询快、召回高,代价是显著的内存占用与较慢的构建速度。它的三个关键参数分别影响图结构(构建期)与搜索广度(查询期)。调参的基本方法是先固定构建参数,再单独扫查询参数,用评测集找到延迟与召回的平衡点。
基本信息
| 定位 | 近似最近邻检索的图索引结构 |
|---|---|
| 优点 | 查询延迟低,召回率高 |
| 代价 | 内存占用大,构建耗时,增量更新成本较高 |
| 构建期参数 | 控制每个节点的连接数量与构建搜索广度 |
| 查询期参数 | 控制检索时的搜索广度 |
| 调参前提 | 必须有带标准答案的评测集,否则无法判断优劣 |
三个关键参数
| 参数 | 作用 | 取值思路 |
|---|---|---|
| 连接数 | 每个节点保留的邻居数量 | 调大提升召回,内存与构建时间同步上升 |
| 构建搜索广度 | 构建时搜索的候选宽度 | 调大能改善图质量,但构建更慢 |
| 查询搜索广度 | 查询时搜索的候选宽度 | 调大提升召回,延迟随之增加 |
| 距离度量 | 相似度计算方式 | 必须与嵌入模型的训练方式匹配 |
| 内存预算 | 索引常驻内存的需求量 | 按数据规模与维度预留,别按压缩后的估算 |
典型使用场景
- 在线语义检索:对延迟敏感的问答与搜索链路
- 大规模去重:在海量文本中找近似内容
- 推荐召回:按向量相似度筛候选集
- 图像或音视频检索:视觉特征向量的近邻查询
- 多租户检索:结合元数据过滤缩小搜索范围
建索引与调参示例
建索引与调参示例
-- 建索引:连接数与构建广度在创建时指定
CREATE INDEX ON docs USING hnsw (embedding vector_cosine_ops)
WITH (m = 16, ef_construction = 64);
-- 查询期:提高搜索广度提升召回,代价是延迟
SET hnsw.ef_search = 100;
SELECT id FROM docs ORDER BY embedding <=> :q LIMIT 10;
-- 距离度量要与嵌入模型匹配:余弦、内积或欧氏距离
-- 调参顺序:先固定构建参数,再单独扫查询参数效果与成本的权衡
| 调整 | 召回 | 延迟 | 内存 |
|---|---|---|---|
| 提高连接数 | 上升 | 基本不变 | 明显上升 |
| 提高构建搜索广度 | 上升 | 基本不变 | 构建时间上升 |
| 提高查询搜索广度 | 上升 | 上升 | 基本不变 |
| 减少过滤范围 | 下降 | 下降 | 不变 |
| 换更低维度向量 | 可能下降 | 下降 | 下降 |
先固定构建参数、再单独扫查询参数:两个变量一起改,就无法判断收益来自哪里,评测结果也没法复用。
为了召回把搜索广度调得很高,会吃掉全部优化收益:延迟回到暴力搜索的水平,索引就白建了。