向量索引
本文介绍 StarRocks 的向量索引功能,以及如何使用该功能进行近似最近邻搜索(ANNS)。
仅 v3.4 及以上版本的存算一体集群支持向量索引功能。
概述
StarRocks 目前支持的向量索引是基于 Segment 文件的索引。索引记录了搜索项与 Segment 文件中数据行号的映射关系,通过快速查找索引文件,可以直接定位到相应数据行,避免了暴力的向量距离计算。StarRocks 当前支持两种类型的向量索引,分别为倒排乘积量化(IVFPQ)和分层小世界图(HNSW),它们各自具有不同的组织方式。
倒排乘积量化(IVFPQ)
倒排乘积量化(Inverted File with Product Quantization,简称 IVFPQ)是一种用于大规模高维向量的近似最近邻搜索方法,广泛应用于深度学习和机器学习中的向量检索任务。IVFPQ 主要包括两个部分:倒排文件和乘积量化。
- 倒排文件(Inverted File):这是一种索引方法,将数据集分为多个聚类(或称为 Voronoi 单元),每个聚类有一个中心,所有数据点根据距离分配到最近的聚类中心。查询时,只需在与被查询向量最接近的聚类中查找,从而显著缩小搜索范围和计算复杂度。
- 乘积量化**(Product Quantization)**:这是一种压缩数据的方法,它将高维向量分割为多个子向量,并对每个子向量进行量化(即将其映射到预定义的有限集合中的最近点),从而压缩数据,减少存储和计算开销,同时保持一定的精度。
IVFPQ 结合了倒排文件和乘积量化,能够在大规模高维数据集上实现高效的近似最近邻搜索。
分层小世界图(HNSW)
分层小世界图(Hierarchical Navigable Small World,简称 HNSW)是一种基于图的高维向量最近邻搜索算法,也广泛应用于向量检索任务。
HNSW 构建了一个层次化的图结构,每层都是一个小世界网络(navigable small world graph,简称 NSW)。在 NSW 图中,每个节点代表一个数据点,节点之间的边表示它们的相似性。高层图仅包含部分节点且连接较稀疏,用于快速全局搜索;低层图包含所有节点,连接更密集,用于精确的局部搜索。查询时,HNSW 先在高层进行搜索,定位到近似邻居区域,再逐层向下查找,直至最底层找到最近邻。
HNSW 具有高效率和高精度的特点,适用于多种数据和查询分布情况。
IVFPQ 与 HNSW 的对比
- 数据压缩****比:IVFPQ 压缩比较高(约为 1:0.15),但需进行精排计算以获得最终排序结果,因此计算开销和延迟较大;HNSW 压缩比较低(约为 1:0.8),但无需额外精排,因此计算开销和延迟更低。
- 召回率调整:两种索引均可通过参数调整召回率(Recall),但 IVFPQ 在相同召回率下的计算成本更高。
- 缓存策略:IVFPQ 可通过调整索引数据块的缓存占比来平衡内存成本和计算延迟,但当前 HNSW 仅支持全量 文件缓存。
使用方法
每张表只支持创建一个向量索引。
前提条件
在创建向量索引之前,需要通过设置FE配置项 enable_experimental_vector
为 true
来启用向量索引功能。
您可以通过以下命令动态启用此功能:
ADMIN SET FRONTEND CONFIG ("enable_experimental_vector" = "true");
要永久启用此功能,需在 FE 配置文件 fe.conf 中添加 enable_experimental_vector = true
并重启 FE。
创建向量索引
以下示例在建表时创建向量索引。您也可以向现有表中添加向量索引,详见添加向量索引。
- 以下示例基于
hnsw
表中的vector
列创建 HNSW 向量索引hnsw_vector
。-
CREATE TABLE hnsw (
id BIGINT(20) NOT NULL COMMENT "",
vector ARRAY<FLOAT> NOT NULL COMMENT "",
INDEX hnsw_vector (vector) USING VECTOR (
"index_type" = "hnsw",
"dim"="5",
"metric_type" = "l2_distance",
"is_vector_normed" = "false",
"M" = "16",
"efconstruction" = "40"
)
) ENGINE=OLAP
DUPLICATE KEY(id)
DISTRIBUTED BY HASH(id) BUCKETS 1;
-
- 以下示例基于
ivfpq
表中的vector
列创建 IVFPQ 向量索引ivfpq_vector
。-
CREATE TABLE ivfpq (
id BIGINT(20) NOT NULL COMMENT "",
vector ARRAY<FLOAT> NOT NULL COMMENT "",
INDEX ivfpq_vector (vector) USING VECTOR (
"index_type" = "ivfpq",
"dim"="5",
"metric_type" = "l2_distance",
"is_vector_normed" = "false",
"nbits" = "16",
"nlist" = "40"
)
) ENGINE=OLAP
DUPLICATE KEY(id)
DISTRIBUTED BY HASH(id) BUCKETS 1;
-
索引构建参数
USING VECTOR
- 默认值:N/A
- **是否必填:**是
- 描述:创建向量索引。
index_type
- 默认值:N/A
- **是否必填:**是
- 描述:向量索引类型。有效值为
hnsw
和ivfpq
。
dim
- 默认值:N/A
- **是否必填:**是
- 描述:索引的维度。在索引构建完成后,不符合维度要求的向量将被拒绝写入至对应列。必须为大于等于
1
的整数。
metric_type
- 默认值:N/A
- 是否必填:是
- 描述:向量索引的度量类型(测量函数)。有效值:
l2_distance
:欧几里得距离。值越小,相似度越高。cosine_similarity
:余弦相似度。值越大,相似度越高。
is_vector_normed
- 默认值:false
- 是否必填:否
- 描述:是否已对向量进行归一化。有效值为
true
和false
。仅在metric_type
为cosine_similarity
时生效。若向量已归一化,计算所得距离值将介于 [-1, 1] 范围内。向量必须满足平方和为1
的条件,否则将返回错误。
M
- 默认值:16
- 是否必填:否
- 描述:HNSW 专用参数。每个新元素在图构建过程中所创建的双向连接数量。必须为大于等于
2
的整数。M
值直接影响图构建和搜索的效率与精度。在图构建过程中,每个顶点会尝试与其最近的M
个顶点建立连接。如果顶点已有M
个连接,但发现一个更近的顶点,则会删除最远的连接并与更近的顶点建立新连接。向量搜索会从一个入口点开始,沿着已连接的顶点找到最近邻。因此,M
值越大,每个顶点的搜索范围越大,搜索效率越高,但图构建和存储的成本也会增加。
efconstruction
- 默认值:40
- 是否必填:否
- 描述:HNSW 专用参数。用于控制图构建过程中的搜索深度。必须为大于等于
1
的整数。具体来说,efconstruction
定义了图构建过程中每个顶点的候选列表大小,用于存储当前顶点的最近邻候选项。efconstruction
值越大,在图构建过程中考虑的最近邻候选项越多,图的质量(如连通性)越好,但同时图构建的时间和计算复杂度也会增加。
nbits
- 默认值:16
- 否必填:否
- 描述:IVFPQ 专用参数。表示乘积量化(PQ)的精度。必须为
8
的倍数。在 IVFPQ 中,每个向量被分成多个子向量,然后每个子向量被量化。nbits
定义了量化的精度,即每个子向量被量化为多少位的二进制数。nbits
值越大,量化精度越高,但存储和计算成本也会增加。
nlist
- 默认值:16
- 是否必填:否
- 描述:IVFPQ 专用参数。表示聚类数量,或倒排列表数量。必须为大于等于
1
的整数。在 IVFPQ 中,数据集被分成多个聚类,每个聚类的中心对应一个倒排列表。向量搜索首先找到距离数据点最近的聚类中心,然后在对应的倒排列表中检索最近邻。因此,nlist
值会影响搜索的准确性和效率。nlist
值越大,聚类的粒度越精细,搜索准确性越高,但搜索复杂性也随之提高。
M_IVFPQ
- 是否必填:是
- 描述:IVFPQ 专用参数。将原始向量分割成的子向量的个数。IVFPQ 索引会将一个
dim
维度的向量分割成M_IVFPQ
个等长子向量。因此,该值必须是dim
值的一个因数。
添加向量索引
可以使用 CREATE INDEX 或 ALTER TABLE ADD INDEX 向现有表中添加向量索引。
示例:
CREATE INDEX ivfpq_vector
ON ivfpq (vector)
USING VECTOR (
"index_type" = "ivfpq",
"metric_type" = "l2_distance",
"is_vector_normed" = "false",
"dim"="5",
"nlist" = "256",
"nbits"="10"
);
ALTER TABLE ivfpq
ADD INDEX ivfpq_vector (vector)
USING VECTOR (
"index_type" = "ivfpq",
"metric_type" = "l2_distance",
"is_vector_normed" = "false",
"dim"="5",
"nlist" = "256",
"nbits"="10"
);
管理向量索引
查看向量索引
您可以使用 SHOW CREATE TABLE 语句查看向量索引的定义:
示例:
mysql> SHOW CREATE TABLE hnsw \G
*************************** 1. row ***************************
Table: hnsw
Create Table: CREATE TABLE hnsw (
id bigint(20) NOT NULL COMMENT "",
vector array<float> NOT NULL COMMENT "",
INDEX index_vector (vector) USING VECTOR("dim" = "5", "efconstruction" = "40", "index_type" = "hnsw", "is_vector_normed" = "false", "M" = "512", "metric_type" = "l2_distance") COMMENT ''
) ENGINE=OLAP
DUPLICATE KEY(id)
DISTRIBUTED BY HASH(id) BUCKETS 1
PROPERTIES (
"compression" = "LZ4",
"fast_schema_evolution" = "true",
"replicated_storage" = "false",
"replication_num" = "3"
);
1 row in set (0.00 sec)
删除向量索引
您可以使用 DROP INDEX 或 ALTER TABLE DROP INDEX 删除向量索引。
DROP INDEX ivfpq_vector ON ivfpq;
ALTER TABLE ivfpq DROP INDEX ivfpq_vector;
使用向量索引进行近似最近邻搜索(ANNS)
在执行向量搜索之前,请确保 FE 配置项 enable_experimental_vector
设置为 true
。