标量索引
Milvus 支持结合标量字段和向量字段的过滤搜索。为了提高涉及标量字段的搜索效率,Milvus 从 2.1.0 版开始引入了标量字段索引。本文将概述 Milvus 中的标量字段索引,帮助您了解其意义和实现方法。
概述
在 Milvus 中进行向量相似性搜索时,可以使用逻辑操作符将标量字段组织成布尔表达式。
当 Milvus 收到带有这种布尔表达式的搜索请求时,它会将布尔表达式解析为抽象语法树(AST),以生成用于属性筛选的物理计划。然后,Milvus 在每个分段中应用物理计划,生成一个比特集作为过滤结果,并将结果作为向量搜索参数,以缩小搜索范围。在这种情况下,向量搜索的速度在很大程度上依赖于属性过滤的速度。
分段属性过滤
标量字段索引是一种确保属性过滤速度的方法,它以特定方式对标量字段值进行排序,以加快信息检索速度。
标量字段索引算法
Milvus 的标量字段索引算法旨在实现低内存占用率、高过滤效率和短加载时间。这些算法主要分为两类:自动索引和反转索引。
自动索引
Milvus 提供了AUTOINDEX
选项,让你无需手动选择索引类型。调用create_index
方法时,如果没有指定index_type
,Milvus 会根据数据类型自动选择最合适的索引类型。
下表列出了 Milvus 支持的数据类型及其相应的自动索引算法。
数据类型 | 自动索引算法 |
---|---|
VARCHAR | 反转索引 |
INT8 | 反转索引 |
INT16 | 反转索引 |
INT32 | 反转索引 |
INT64 | 反转索引 |
FLOAT | 反转索引 |
二进制 | 反转索引 |
反转索引
反转索引提供了一种灵活的方法,可通过手动指定索引参数为标量字段创建索引。这种方法适用于各种情况,包括点查询、模式匹配查询、全文检索、JSON 搜索、布尔搜索,甚至前缀匹配查询。
Milvus 中实现的倒排索引由全文搜索引擎库Tantivy 提供支持。Tantivy 确保 Milvus 中的倒排索引既高效又快速。
倒排索引有两个主要部分:术语字典和倒排列表。术语词典包括按字母顺序排列的所有标记词,而倒排列表则包含每个词出现的文档列表。这种设置使得点查询和范围查询比暴力搜索更快、更有效。
倒排索引图
使用倒排索引的优势在以下操作中尤为明显:
- 点查询:例如,在搜索包含单词Milvus 的文档时,首先要检查术语字典中是否存在Milvus。如果没有找到,则没有文档包含该词。但如果找到了,则会检索与Milvus相关的倒序列表,指出包含该词的文档。这种方法比在一百万个文档中进行暴力搜索要有效得多,因为排序后的术语词典大大降低了查找Milvus 这个词的时间复杂度。
- 范围查询:范围查询(如查找单词字母大于very 的文档)的效率也能通过排序术语字典得到提高。这种方法比暴力搜索更有效,能提供更快、更准确的结果。
测试结果
为了证明标量索引在 Milvus 中提供的性能改进,我们进行了一项实验,比较了在原始数据上使用倒排索引和暴力搜索的几种表达式的性能。
实验包括在两种条件下测试各种表达式:倒排索引和暴力搜索。为确保公平性,每次测试都使用相同的 Collections,保持相同的数据分布。每次测试前,都会释放 Collections,并丢弃和重建索引。此外,每次测试前都会执行一次热查询,以尽量减少冷数据和热数据的影响,并且每次查询都会执行多次,以确保准确性。
对于包含100 万条记录的数据集,使用反转索引最多可将点查询的性能提高30 倍。对于更大的数据集,性能提升可能会更显著。
性能建议
要充分利用 Milvus 在标量字段索引方面的能力,并释放其在向量相似性搜索方面的威力,你可能需要一个模型来根据你所拥有的数据估算所需的内存大小。
下表列出了 Milvus 支持的所有数据类型的估算功能。
数值字段
数据类型 内存估算函数(MB) INT8 行数 *12/ 1024 / 1024 INT16 行数 *12/ 1024 / 1024 INT32 行数 *12/ 1024 / 1024 INT64 行数 *24/ 1024 / 1024 FLOAT32 行数 *12/ 1024 / 1024 二进制 行数 *24/ 1024 / 1024 字符串字段
字符串长度 内存估算函数(MB) (0, 8] 行数 *128/ 1024 / 1024 (8, 16] 行数 *144/ 1024 / 1024 (16, 32] 行数 *160/ 1024 / 1024 (32, 64] 行数 *192/ 1024 / 1024 (64, 128] 行数 *256/ 1024 / 1024 (128, 65535] 行数 *strLen * 1.5/ 1024 / 1024