Milvus索引说明
一、 向量索引 (Vector Index)
向量索引用于快速、近似地找到与目标向量最相似的 Top-K 个向量。由于精确搜索(如暴力搜索)在海量数据下非常耗时,所以我们使用近似最近邻(ANN - Approximate Nearest Neighbor)索引来平衡搜索速度和精度。
Milvus 通过 IndexType(索引类型)和 MetricType(度量类型)来定义一个向量索引。
-
MetricType (度量类型):决定了"相似度"的计算方式。
L2(欧氏距离):距离越小越相似。IP(内积):值越大越相似,常用于计算余弦相似度(需先将向量归一化)。JACCARD/HAMMING:用于计算集合或二进制向量的相似度。COSINE:适用于自然语言处理,数值越大越相似。
(1)主要的向量索引类型及其区别和效果
下面是一张总结表格,详细比较了主流索引:
| 索引类型 | 全称/类别 | 原理简介 | 优点 | 缺点 | 典型应用场景 |
|---|---|---|---|---|---|
| FLAT | 精确索引 | 暴力搜索(Brute-Force)。对库中每个向量都与查询向量进行计算。 | 100% 精确,不损失召回率。 | 数据量大时速度极慢,不适用于生产环境。 | 数据集很小(< 10万),或用于验证其他索引的召回率。 |
| IVF_FLAT | 倒排文件 | 1. 聚类 :将向量库预先划分为多个簇(nlist)。 2. 查找 :搜索时,仅计算并返回查询向量最邻近的 nprobe 个簇内的向量。 |
搜索速度非常快,构建索引快。 | 精度有损 ,nprobe 越小,速度越快但召回率越低。 |
通用场景 ,对搜索速度要求高,能接受可控的精度损失。是最常用的索引之一。 |
| IVF_SQ8 | 倒排文件 + 量化 | 在 IVF_FLAT 的基础上,对每个向量进行标量量化(Scalar Quantization) ,将原本的 float32 压缩成 int8。 |
内存占用大幅降低(约为原来的 1/4),同时保持了 IVF_FLAT 的速度。 | 精度进一步损失,比 IVF_FLAT 略低。 | 内存紧张的场景,数据量巨大,能接受稍低的精度。 |
| IVF_PQ | 倒排文件 + 量化 | 在 IVF_FLAT 的基础上,对每个向量进行乘积量化(Product Quantization),压缩率更高。 | 内存占用极低 ,搜索速度极快。 | 精度损失最大 ,效果最"粗暴"。"分段"数 m 越大,精度越高但内存占用也越大。 |
超大规模数据集(亿级以上),对召回率要求不极端,但对内存和速度要求极高。 |
| HNSW | 图索引 | 构建一个多层的图(Hierarchical Navigable Small World graph)。搜索时从顶层开始,逐层向下,像在地图上导航一样快速找到目标。 | 速度和召回率的综合表现极佳 ,是当前性能最好的索引之一(尤其是在不考虑内存占用的情况下)。 | 构建索引非常慢 ,且内存占用非常高(原始向量+图结构)。 | 对搜索延迟(Latency)要求极为苛刻的在线服务,内存充足。 |
| DISKANN | 磁盘索引 | 专为磁盘存储设计的图索引,通过巧妙的缓存和预取机制,高效地从磁盘读取向量数据进行搜索。 | 在 SSD 上性能优异 ,内存占用极低 (只加载少量热点数据),能处理远超内存容量的数据集。 | 对存储介质(SSD)性能有要求,搜索延迟可能略高于纯内存的 HNSW,但吞吐量高。 | 超大规模数据集 (十亿、百亿级),内存严重不足,但拥有高速 SSD 的场景。 |
| ANNOY | 树索引 | 构建多棵随机投影树,搜索时在树中进行快速定位。 | - | 在 Milvus 中已不推荐使用,性能通常不如 HNSW 或 IVF 系列。 | - |
| BIN_FLAT | 二进制精确索引 | 针对二进制向量的暴力搜索。 | 精确,不损失召回率。 | 速度慢。 | 二进制向量的小数据集。 |
| BIN_IVF_FLAT | 二进制倒排文件 | 针对二进制向量的 IVF_FLAT。 | 速度快。 | 精度有损。 | 二进制向量的大数据集。 |
(2)索引效果和选择策略
选择哪种索引,本质上是在 速度(Speed)、精度(Recall)、内存(Memory) 这"不可能三角"中做取舍。
-
探索阶段 / 小数据量(< 100万):
- 首选
FLAT。确保数据和逻辑没问题,再考虑升级索引,因为它保证了 100% 的召回率,是检验其他索引效果的"黄金标准"。
- 首选
-
通用生产环境(百万到数千万级别,内存充足):
- 首选
IVF_FLAT 。速度和精度的完美平衡点,通过调整nlist和nprobe参数,可以灵活地在速度和召回率之间做调整。是绝大多数场景的默认首选。 - 如果内存稍紧张,考虑
IVF_PQ或IVF_SQ8。
- 首选
-
追求极致搜索性能(低延迟,内存充足):
- 首选
HNSW 。如果你的应用是搜索引擎、推荐系统等对单次查询延迟极其敏感(毫秒级),并且服务器内存非常充裕(通常是数据量的 3-5 倍或更多),HNSW能提供最顶级的查询体验,几乎可以媲美 FLAT 的召回率和极快的速度。注意:构建索引过程会消耗大量时间和内存。
- 首选
-
超大规模,内存严重受限(亿级以上):
- 首选
DISKANN 。当数据量大到无法完全载入内存时,DISKANN是解决方案。它允许你用远低于数据量本身的内存来处理海量向量,性能在 SSD 上表现优秀。 - 在此之前,可以尝试
IVF_PQ,看看其量化后的精度是否满足业务需求,因为其内存占用比DISKANN还要低。
- 首选
二、 标量索引 (Scalar Index)
标量索引用于对非向量字段(如 ID、标签、时间戳、类别等)进行加速过滤搜索。在进行 query 时,如果使用了 expr(表达式)过滤,标量索引能极大地提升过滤效率。
Milvus 支持多种标量索引类型,通常会自动选择,但也可以手动指定:
INVERTED (倒排索引) :最常用、最通用 的索引。它为每个字段值创建一个"倒排列表",记录了该值出现的所有实体 ID。非常适合field in [value1, value2]这类精确匹配查询。STL_SORT :对数值类型的字段非常高效,排序后可以进行二分查找。适合field > value或field < value这类范围查询。TRIE (前缀树) :主要用于字符串字段的前缀匹配查询,例如field like "abc%"。
使用建议 :
对于经常用作过滤条件的标量字段,一定要创建索引。例如,在"搜图"的同时,要求"图片所属用户ID=123",那么为"用户ID"字段创建倒排索引,搜索速度会快几个数量级。
三、总结与实践建议
| 需求场景 | 推荐索引 (Vector) | 推荐索引 (Scalar) | 关键参数(需要调优) |
|---|---|---|---|
| 数据量小 / 需要绝对精确 | FLAT |
无需 | - |
| 通用场景,平衡速度与精度 | IVF_FLAT |
INVERTED |
nlist (建库), nprobe (查询) |
| 内存有限,速度要快 | IVF_SQ8, IVF_PQ |
INVERTED |
nlist, nprobe, m (PQ) |
| 搜索延迟极度敏感,内存充足 | HNSW |
INVERTED |
M, efConstruction (建库), ef (查询) |
| 数据量超大,内存严重不足 | DISKANN |
INVERTED |
search_list_size, k |
最后,切记:
索引的选择和调优没有银弹。最好的方法是:
- 明确你的业务需求(对速度、精度的底线要求)。
- 准备一小部分有代表性的数据。
- 使用
Milvus' Benchmark工具或自己编写脚本,对不同索引和参数组合进行压力测试,找到最适合你当前场景的配置。