首批通过分布式安全可靠测评,为关键业务系统打造
内存稀疏索引
更新时间:2026-05-20 17:37:12
本文档介绍 OceanBase 数据库中基于内存的稀疏向量索引的创建、搜索和使用方法。简称内存稀疏索引。
说明
该功能在当前版本为实验特性,不建议在生产环境使用。
内存稀疏索引是 OceanBase 数据库针对稀疏向量数据(大部分元素为零的向量)提供的高效索引类型,需要将索引完整的载入内存,支持 DML 和实时搜索。为了提升稀疏向量的查询性能,OceanBase 数据库集成了 VSAG 算法库的稀疏向量索引(SINDI),该索引在性能上优于基于磁盘的稀疏向量索引,适合在内存资源充足的情况下使用。
功能支持
内存稀疏索引支持以下功能:
| 模块 | 功能点 | 介绍 |
|---|---|---|
| DDL | 建表时创建稀疏向量索引 | 可以在创建表的时候,在 SPARSEVECTOR 列上创建稀疏向量索引。最大支持 500,000 维。 |
| DDL | 后建稀疏向量索引 | 支持在已存在表的 SPARSEVECTOR 列上创建稀疏向量索引。最大支持 500,000 维。 |
| DML | 插入、更新、删除 | 与常规向量索引的 DML 操作语法完全一致。 |
| 搜索 | 向量搜索 | 支持使用 SQL 函数进行搜索。 |
| 搜索 | 查询参数 | 支持在搜索时通过 parameters 子句设置查询级参数。 |
| DBMS_VECTOR | REBUILD_INDEX |
执行索引全量重建。 |
索引语法及说明
创建
内存稀疏索引支持建表时创建和后建两种方式。创建时需要注意:
- 创建稀疏向量索引的列最大支持 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, ...)
);
支持在已经存在表的 SPARSEVECTOR 列上创建稀疏向量索引。
CREATE VECTOR INDEX index_name ON table_name(column_name) 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 子句设置,查询参数优先级更高。 |
搜索
稀疏向量索引的搜索语法与稠密向量索引类似,使用 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。
搜索语法要求:
- 必须指定
APPROXIMATE/APPROX关键字,搜索才会使用向量索引而非全表扫描。 - 必须包含
ORDER BY和LIMIT子句。 ORDER BY只支持单个向量条件。LIMIT + OFFSET的取值范围为(0, 16384]。- 不指定
LIMIT子句会报错。
距离函数使用规则:
- 指定
APPROXIMATE/APPROX,调用当前版本支持的距离函数,且与向量索引算法匹配,搜索会使用向量索引。 - 指定
APPROXIMATE/APPROX,距离函数与向量索引算法不匹配,搜索不会使用向量索引,但也不会报错。 - 指定
APPROXIMATE/APPROX,如果距离函数为当前版本不支持的距离函数,搜索不会使用向量索引,且会报错。 - 未指定
APPROXIMATE/APPROX,调用当前版本支持的距离函数,搜索不会使用向量索引,但也不会报错。
其他说明:
WHERE条件会作为向量索引搜索的过滤条件。- 召回率受构建参数和搜索参数的影响。
- 索引搜索参数可以在创建索引时进行设置。如果在索引创建完成后需要调整,可以通过 DBMS_VECTOR.REBUILD_INDEX 修改表级属性,也可以在查询时通过指定查询级别参数
ef_search进行调整。
内存稀疏索引特有要求:
- 查询参数的优先级:
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时有效。
创建、更新、搜索与删除示例
建表时创建
创建测试表 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;
搜索
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