基于内存的稀疏向量索引
本文档介绍 SeekDB 基于内存的稀疏向量索引 的创建、搜索和使用方法。
概述
基于内存的稀疏向量索引是 SeekDB 针对稀疏向量数据(大部分元素为零的向量)提供的高效索引类型。基于内存的稀疏向量索引需要将索引完整的载入内存,支持 DML 和实时搜索。
为了提升稀疏向量的查询性能,SeekDB 集成了 VSAG 算法库的稀疏向量索引(SINDI),该索引在性能上优于基于磁盘的稀疏向量索引,适合在内存资源充足的情况下使用。
功能支持
基于内存的稀疏向量索引支持以下功能:
| 模块 | 功能点 | 介绍 |
|---|---|---|
| DDL | 建表时创建稀疏向量索引 | 可以在创建表的时候,在 SPARSEVECTOR 列上创建稀疏向量索引。最大支持 500,000 维。 |
| DDL | 后建稀疏向量索引 | 支持在已存在表的 SPARSEVECTOR 列上创建稀疏向量索引。最大支持 500,000 维。 |
| DML | 插入、更新、删除 | 与常规向量索引的 DML 操作语法完全一致。 |
| 搜索 | 向量搜索 | 支持使用 SQL 函数进行搜索。 |
| 搜索 | 查询参数 | 支持在搜索时通过 parameters 子句设置查询级参数。 |
| DBMS_VECTOR | REFRESH_INDEX | 执行索引增量刷新。 |
| DBMS_VECTOR | REBUILD_INDEX | 执行索引全量重建。 |
索引内存估算与实际占用查询
支持通过 DBMS_VECTOR 系统包进行索引内存估算,用法与稠密索引一致,这里仅介绍稀疏向量索引的特殊要求:
IDX_TYPE参数必须指定为SINDI,大小写不敏感。
创建语法及说明
基于内存的稀疏向量索引支持建表时创建和后建两种方式。创建时需要注意:
- 创建稀疏向量索引的列最大支持 500,000 维。
- 创建稀疏向量索引必须指定在
SPARSEVECTOR类型的列上。 - 创建索引必须带有
VECTOR关键字。 - 索引类型必须指定为
sindi,表示创建基于内存的稀疏向量索引。 - 距离算法仅支持
inner_product(内积)。 - 后建索引的参数和说明与建表时创建索引一致。
建表时创建
支持使用 CREATE TABLE 语句创建稀疏向量索引。
语法
CREATE TABLE table_name (
column_name1 data_type1,
column_name2 SPARSEVECTOR,
...,
VECTOR INDEX index_name (column_name2) WITH (param1=value1, param2=value2, ...)
);
参数说明
| 参数 | 默认值 | 取值范围 | 是否必填 | 说明 | 备注 |
|---|---|---|---|---|---|
distance | inner_product | 是 | 指定向量距离算法类型。 | 稀疏向量索引仅支持内积(inner_product)作为距离算法。 | |
type | sindi | 是 | 指定索引算法类型。 | 表示创建基于内存的稀疏向量索引。 | |
lib | vsag | vsag | 否 | 指定向量索引库类型。 | 目前仅支持 VSAG 向量库。 |
prune | false | true/false | 否 | 是否对向量执行剪枝。 | prune 为 true 时,才需要设置 refine 和 drop_ratio_build 参数;prune 为 false 时,可以提供全精度的搜索,如果设置 refine 为 true 或者 drop_ratio_build 非 0 会报错。 |
refine | false | true/false | 否 | 是否需要重排。 | 取值为 true 时,会对搜索结果获取原始稀疏向量来进行高精度的距离计算并 重排,意味着需要多存储一份原始向量数据。仅在 prune=true 时可设置。 |
drop_ratio_build | 0 | [0, 0.9] | 否 | 对稀疏向量数据进行剪枝的比例。 | 新插入一条稀疏向量,会按照值大小裁剪掉 query_length * drop_ratio_build 个最小的值。如果 refine 为 true,则会保持原始向量数据,否则只保留裁剪后的数据。仅在 prune=true 时可设置。 |
drop_ratio_search | 0 | [0, 0.9] | 否 | 对搜索稀疏向量数值进行剪枝的比例。 | 取值越大,剪枝越多,准确率越低,性能越高。也可以在搜索时通过 parameters 子句设置,查询参数优先级更高。 |
refine_k | 4.0 | [1.0, 1000.0] | 否 | 表示参与重排的比例。 | 搜索 limit_k * refine_k 项结果,并获取原始向量进行重排。refine=true 的情况下才有意义。也可以在搜索时通过 parameters 子句设置,查询参数优先级更高。 |
后建索引
支持在已经存在表的 SPARSEVECTOR 列上创建稀疏向量索引。
语法
CREATE VECTOR INDEX index_name ON table_name(column_name) WITH (param1=value1, param2=value2, ...);
参数说明
参数说明与建表时创建索引一致,详见上文。
创建、更新与删除示例
建表时创建
创建 测试表 sparse_t1 并创建稀疏向量索引:
CREATE TABLE sparse_t1 (
c1 INT PRIMARY KEY,
c2 SPARSEVECTOR,
VECTOR INDEX sparse_idx1(c2)
WITH (lib=vsag, type=sindi, distance=inner_product)
);
向测试表插入稀疏向量数据:
INSERT INTO sparse_t1 VALUES(1, '{1:0.1, 2:0.2, 3:0.3}');
INSERT INTO sparse_t1 VALUES(2, '{3:0.3, 2:0.2, 4:0.4}');
INSERT INTO sparse_t1 VALUES(3, '{3:0.3, 4:0.4, 5:0.5}');
搜索测试表:
SELECT * FROM sparse_t1;
返回结果如下:
+----+---------------------+
| c1 | c2 |
+----+---------------------+
| 1 | {1:0.1,2:0.2,3:0.3} |
| 2 | {2:0.2,3:0.3,4:0.4} |
| 3 | {3:0.3,4:0.4,5:0.5} |
+----+---------------------+
3 rows in set
后建索引
创建 测试表后再创建稀疏向量索引:
CREATE TABLE sparse_t2 (
c1 INT PRIMARY KEY,
c2 SPARSEVECTOR
);
CREATE VECTOR INDEX sparse_idx2 ON sparse_t2(c2)
WITH (lib=vsag, type=sindi, distance=inner_product,
prune=true, refine=true, drop_ratio_build=0.1,
drop_ratio_search=0.5, refine_k=2.0);
向测试表插入稀疏向量数据:
INSERT INTO sparse_t2 VALUES(1, '{1:0.1, 2:0.2, 3:0.3}');
搜索测试表:
SELECT * FROM sparse_t2;
返回结果如下:
+----+---------------------+
| c1 | c2 |
+----+---------------------+
| 1 | {1:0.1,2:0.2,3:0.3} |
+----+---------------------+
1 row in set
更新
更新稀疏向量数据时,索引会自动维护:
UPDATE sparse_t1 SET c2 = '{1:0.1}' WHERE c1 = 1;
删除
删除操作与常规向量索引一致,直接删除数据即可:
DELETE FROM sparse_t1 WHERE c1 = 1;
搜索
稀疏向量索引的搜索语法与稠密向量索引类似,使用 APPROXIMATE/APPROX 关键字进行近似最近邻搜索。
语法
SELECT ... FROM table_name
ORDER BY inner_product(column_name, query_vector) [APPROXIMATE|APPROX]
LIMIT n [PARAMETERS(param1=value1, param2=value2)];
其中:
column_name:稀疏向量索引创建时指定的SPARSEVECTOR列。query_vector:查询向量,可以是稀疏向量格式的字符串,如'{1:2.4, 3:1.5}'。n:返回的结果行数。PARAMETERS:可选的查询级参数,用于设置drop_ratio_search和refine_k。
搜索使用说明
详细要求请参见稠密向量索引。这里仅介绍稀疏向量索引的特殊要求:
- 查询参数的优先级:
PARAMETERS设置的查询级参数 > 构建索引设置的查询参数 > 默认值。 drop_ratio_search:取值[0, 0.9],默认值0。对查询稀疏向量数值进行剪枝的比例,取值越大,剪枝越多,准确率越低,性能越高。按照值大小剪枝掉query_length * drop_ratio_search个最小的值。由于全部裁剪掉没有意义,因此最少都会保留一个值。refine_k:取值[1.0, 1000.0],默认值为4.0。表示参与重排的比例,查询limit_k * refine_k项结果,并获取原始向量进行重排。仅在refine=true时有效。
使用示例
普通查询
CREATE TABLE t1 (
c1 INT PRIMARY KEY,
c2 SPARSEVECTOR,
VECTOR INDEX idx1(c2)
WITH (lib=vsag, type=sindi, distance=inner_product)
);
INSERT INTO t1 VALUES(1, '{1:0.1, 2:0.2, 3:0.3}');
INSERT INTO t1 VALUES(2, '{3:0.3, 2:0.2, 4:0.4}');
INSERT INTO t1 VALUES(3, '{3:0.3, 4:0.4, 5:0.5}');
INSERT INTO t1 VALUES(4, '{5:0.5, 4:0.4, 6:0.6}');
INSERT INTO t1 VALUES(5, '{5:0.5, 6:0.6, 7:0.7}');
SELECT * FROM t1
ORDER BY negative_inner_product(c2, '{3:0.3, 4:0.4}')
APPROXIMATE LIMIT 4;
返回结果如下:
+----+---------------------+
| c1 | c2 |
+----+---------------------+
| 2 | {2:0.2,3:0.3,4:0.4} |
| 3 | {3:0.3,4:0.4,5:0.5} |
| 4 | {4:0.4,5:0.5,6:0.6} |
| 1 | {1:0.1,2:0.2,3:0.3} |
+----+---------------------+
使用查询参数
SELECT *, negative_inner_product(c2, '{3:0.3, 4:0.4}')
AS score FROM t1
ORDER BY score APPROXIMATE LIMIT 4
PARAMETERS(drop_ratio_search=0.5);
返回结果如下:
+----+---------------------+---------------------+
| c1 | c2 | score |
+----+---------------------+---------------------+
| 4 | {4:0.4,5:0.5,6:0.6} | -0.1600000113248825 |
| 3 | {3:0.3,4:0.4,5:0.5} | -0.2500000149011612 |
| 2 | {2:0.2,3:0.3,4:0.4} | -0.2500000149011612 |
+----+---------------------+---------------------+
3 rows in set
索引监控与维护
基于内存的稀疏向量索引提供了一些监控视图,且支持使用 DBMS_VECTOR 系统包进行索引维护,包括增量刷新和全量重建。用法与稠密索引一致。