Hologres V5.0版本起支持稀疏向量数据类型SPARSEVECTOR,以及基于SINDI(Sparse Inverted No-redundancy Distance Index)算法的稀疏向量索引。稀疏向量索引利用倒排结构和SIMD加速,针对高维稀疏向量场景(如文本检索、推荐系统)提供高效的近似最近邻检索能力。本文为您介绍稀疏向量索引的适用场景、管理方法、检索方式与性能调优建议。
稀疏向量索引与HGraph索引对比
Hologres支持两种向量索引:稀疏向量索引(SINDI)和HGraph索引。两者适用于不同的数据类型和业务场景,请根据实际需求选择。
稀疏向量索引(SINDI)
稀疏向量仅存储非零元素及其索引位置,采用{索引:值}的形式表示。例如,一个100万维的向量若只有100个非零元素,稀疏表示仅需100个索引-值对,存储和计算效率远高于稠密表示。
稀疏向量索引适用于以下典型场景:
-
文本检索:SPLADE、BGE-M3等模型生成的文本嵌入向量通常为高维稀疏向量。
-
推荐系统:基于用户-物品交互特征构建的稀疏向量。
-
广告特征:基于用户画像和广告属性的稀疏特征向量。
HGraph索引
HGraph是Hologres的稠密向量索引方案,基于图索引算法,适用于低维稠密向量的近似最近邻检索。详细信息请参见HGraph索引使用指南(推荐)。
索引选择
|
对比维度 |
稀疏向量索引(SINDI) |
HGraph索引 |
|
数据类型 |
SPARSEVECTOR |
float4[] |
|
向量维度 |
高维稀疏(千万级维度,非零元素少) |
低维稠密(数百至数千维) |
|
索引算法 |
SINDI |
HGraph |
|
支持距离度量 |
仅InnerProduct |
Euclidean、InnerProduct、Cosine |
|
存储模式 |
全内存 |
纯内存、内存+磁盘 |
|
混合检索 |
支持(同一SQL中组合稀疏与稠密向量查询) |
支持 |
选择建议:
-
如果您的数据来自SPLADE、BGE-M3等稀疏编码模型,或业务场景中向量维度极高但大部分元素为零(如文本嵌入、推荐特征),请选择稀疏向量索引。
-
如果您的数据为图像嵌入、语义向量等低维稠密向量,或需要使用Cosine、Euclidean距离、磁盘存储模式,请选择HGraph索引。
注意事项
-
仅Hologres V5.0及以上版本支持稀疏向量索引。
-
仅列存表和行列共存表支持创建稀疏向量索引,行存表不支持。
-
内存表(Mem Table)中的数据没有稀疏向量索引,执行检索时该部分数据将进行暴力计算。
-
稀疏向量列不支持与HGraph索引共存。同一列只能创建一种类型的向量索引。
-
当前仅支持全内存模式,大规模数据场景请关注内存用量。建议根据数据量评估实例规格。
-
创建稀疏向量索引时,
vectors属性中algorithm仅支持Sindi,distance_method仅支持InnerProduct。不支持使用proxima_vectors属性。
管理稀疏向量索引
创建索引
您可以在建表时或建表后为稀疏向量列创建SINDI索引。
语法:
-- 建表时创建索引
CREATE TABLE <TABLE_NAME> (
<COLUMN_NAME> SPARSEVECTOR,
...
) WITH (
vectors = '{
"<COLUMN_NAME>": {
"algorithm": "Sindi",
"distance_method": "InnerProduct",
"builder_params": {
"use_reorder": <TRUE|FALSE>,
"term_id_limit": <INTEGER>,
"doc_prune_ratio": <FLOAT>,
"window_size": <INTEGER>
}
}}'
);
-- 建表后创建索引
ALTER TABLE <TABLE_NAME> SET (
vectors = '{
"<COLUMN_NAME>": {
"algorithm": "Sindi",
"distance_method": "InnerProduct",
"builder_params": {
"use_reorder": <TRUE|FALSE>,
"term_id_limit": <INTEGER>,
"doc_prune_ratio": <FLOAT>,
"window_size": <INTEGER>
}
}}'
);
数据类型说明:
稀疏向量采用数据类型SPARSEVECTOR,包含无序的键值对,格式如下:'{索引:值, 索引:值, ...}'。其中,索引为不小于1的整数,且须小于term_id_limit参数值;值为浮点数。
示例:'{1:0.1, 50:0.8, 200:0.3}'
参数说明:
|
参数 |
是否必填 |
默认值 |
说明 |
|
algorithm |
是 |
无 |
索引算法,仅支持Sindi。 |
|
distance_method |
是 |
无 |
距离度量方式,仅支持InnerProduct。 |
|
use_reorder |
否 |
false |
是否开启重排序。开启后可提升召回率,推荐在高精度场景中设置为true。 |
|
term_id_limit |
否 |
1000000 |
稀疏向量索引的最大特征维度上限。文本格式中的索引值(1-based)须小于该值。请根据实际数据中的最大索引值设置。 |
|
doc_prune_ratio |
否 |
0.0 |
构建时的文档剪枝比例,取值范围[0.0, 1.0)。值越大,查询性能越好,但召回率会有所下降。 |
|
window_size |
否 |
50000 |
索引构建的窗口大小,取值范围[10000, 60000]。影响内存使用和构建性能。 |
|
use_quantization |
否 |
false |
是否开启量化。开启后可减少内存占用,但可能影响召回率。 |
建表时创建索引示例:
CREATE TABLE sparse_test (
id INT PRIMARY KEY,
vec SPARSEVECTOR
) WITH (
vectors = '{
"vec": {
"algorithm": "Sindi",
"distance_method": "InnerProduct",
"builder_params": {
"use_reorder": true,
"term_id_limit": 1000000,
"doc_prune_ratio": 0.4,
"window_size": 50000
}
}}'
);
修改索引
您可以通过ALTER TABLE修改稀疏向量索引的构建参数。
-- 修改文档剪枝比例
ALTER TABLE sparse_test SET (
vectors = '{
"vec": {
"algorithm": "Sindi",
"distance_method": "InnerProduct",
"builder_params": {
"use_reorder": true,
"term_id_limit": 1000000,
"doc_prune_ratio": 0.6,
"window_size": 50000
}
}}'
);
修改参数后,新参数对后续构建的索引生效。您可以手动执行以下命令触发数据合并(Compaction):
VACUUM <SCHEMA_NAME>.<TABLE_NAME>;
关于数据合并(Compaction)的更多信息,请参见Compaction。
删除索引
将vectors设置为空JSON对象即可删除稀疏向量索引。
ALTER TABLE sparse_test SET (vectors = '{}');
查看索引
通过查询hologres.hg_table_properties系统表查看稀疏向量索引的配置信息。
SELECT property_value
FROM hologres.hg_table_properties
WHERE table_name = 'sparse_test'
AND property_key = 'vectors';
使用稀疏向量进行检索
Hologres提供以下距离计算函数用于稀疏向量检索。
|
函数 |
说明 |
|
approx_inner_product_distance(sparsevector, sparsevector) |
近似检索,使用SINDI索引加速,返回内积距离。 |
|
inner_product_distance(sparsevector, sparsevector) |
精确检索(暴力计算),不使用索引,返回内积距离。 |
稀疏向量仅支持InnerProduct距离度量,不支持approx_cosine_distance、approx_euclidean_distance等函数。如需使用Cosine距离,请对向量进行归一化处理后使用InnerProduct。
近似检索
使用approx_inner_product_distance函数配合ORDER BY ... DESC LIMIT k进行TopK近似检索。查询将自动命中SINDI索引。
SELECT id, approx_inner_product_distance(vec, '{1:0.1, 2:0.2, 3:0.3}') AS dist
FROM sparse_test
ORDER BY dist DESC
LIMIT 5;
精确检索
使用inner_product_distance函数进行精确检索(暴力计算),不走索引,适用于小数据量或需要精确结果的场景。
SELECT id, inner_product_distance(vec, '{1:0.1, 2:0.2, 3:0.3}') AS dist
FROM sparse_test
ORDER BY dist DESC
LIMIT 5;
验证索引是否命中
通过EXPLAIN ANALYZE查看执行计划,确认查询是否命中稀疏向量索引。
EXPLAIN ANALYZE
SELECT product_id,
approx_inner_product_distance(feature, '{1:0.1, 50:0.7}') AS dist
FROM product_features
ORDER BY dist DESC
LIMIT 5;
执行计划中,稀疏向量列出现Vector Filter,则表示已命中稀疏向量索引。
Vector Filter: VectorCond => KNN: '5'::bigint distance_method: approx_inner_product_distance
使用inner_product_distance函数时,执行计划显示Seq Scan(无Vector Filter),表示未使用索引,为暴力计算模式。
使用示例
以下示例展示稀疏向量索引的完整使用流程:建表、写入数据、查询。
-- 1. 创建带稀疏向量索引的表
CREATE TABLE product_features (
product_id INT PRIMARY KEY,
feature SPARSEVECTOR,
product_name TEXT
) WITH (
vectors = '{
"feature": {
"algorithm": "Sindi",
"distance_method": "InnerProduct",
"builder_params": {
"use_reorder": true,
"term_id_limit": 100000,
"window_size": 50000
}
}}'
);
-- 2. 写入数据(稀疏向量使用文本格式 {索引:值, ...},索引从1开始)
INSERT INTO product_features VALUES
(1, '{1:0.1, 50:0.8, 200:0.3}', '商品A'),
(2, '{1:0.2, 100:0.6}', '商品B'),
(3, '{50:0.9, 200:0.1, 500:0.4}', '商品C'),
(4, '{1:0.1, 100:0.5, 200:0.7}', '商品D'),
(5, '{50:0.3, 500:0.8}', '商品E');
-- 3. 查询与目标向量最相似的Top 5商品
SELECT product_id, product_name,
approx_inner_product_distance(feature, '{1:0.1, 50:0.7, 200:0.5}') AS similarity
FROM product_features
ORDER BY similarity DESC
LIMIT 5;
返回结果:
|
product_id |
product_name |
similarity |
|
1 |
商品A |
0.72 |
|
3 |
商品C |
0.68 |
|
4 |
商品D |
0.36 |
|
5 |
商品E |
0.21 |
|
2 |
商品B |
0.02 |
以上返回结果为示例值,实际结果以查询为准。
性能调优
构建参数调优
doc_prune_ratio是影响查询性能最关键的构建参数。增大该值可显著提升查询速度,但会牺牲一定的召回率。
|
doc_prune_ratio值 |
效果 |
|
0.0 |
不剪枝,召回率最高(默认参数下recall@10可达99.99%),但查询性能较低。 |
|
0.4(推荐) |
性能与召回率的良好平衡点。相比0.0查询性能提升约10倍,召回率轻微下降。 |
|
大于0.4 |
查询性能进一步提升,但召回率下降更明显。 |
开启use_reorder(设为true)可在保持高召回率的同时提升查询性能,推荐在高精度场景中开启。
查询参数调优
通过设置GUC参数调整查询时的性能与召回率平衡。
|
GUC参数 |
默认值 |
说明 |
|
hg_vector_sindi_n_candidate |
0 |
查询时的候选集大小。默认值为0,表示取topk × 500。值越大,召回率越高,但查询延迟增加。 |
|
hg_vector_sindi_query_prune_ratio |
0.0 |
查询时的剪枝比例,取值范围[0.0, 0.9]。值越大,查询越快但召回率下降。 |
|
hg_vector_sindi_term_prune_ratio |
0.0 |
查询时的term剪枝比例,取值范围[0.0, 0.9]。不建议使用,对召回率影响较大。 |
|
hg_vector_sindi_use_term_lists_heap_insert |
true |
是否使用堆插入优化。 |
使用示例:
-- 设置查询参数
SET hg_vector_sindi_n_candidate = 500;
SET hg_vector_sindi_query_prune_ratio = 0.8;
-- 执行查询
SELECT id, approx_inner_product_distance(vec, '{1:0.1, 2:0.2}') AS dist
FROM sparse_test
ORDER BY dist DESC
LIMIT 10;
-- 重置为默认值
RESET hg_vector_sindi_n_candidate;
RESET hg_vector_sindi_query_prune_ratio;
场景推荐配置
以sparse-full数据集(884万向量,30109维,99.6%稀疏度)为例,推荐场景配置如下:
|
场景 |
doc_prune_ratio(构建) |
query_prune_ratio(查询) |
n_candidate(查询) |
预期召回率 |
预期p99延迟 |
|
高精度(RAG文本检索) |
0.0~0.2 |
0.7 |
500~1000 |
大于99.8% |
约15 ms |
|
均衡 |
0.4 |
0.8 |
300~500 |
大于99.4% |
约13 ms |
|
高性能(实时检索) |
0.4~0.6 |
0.9 |
500~1000 |
大于96% |
约10 ms |
常见问题
-
Q:创建稀疏向量索引时报错
For Sindi algorithm, only 'InnerProduct' distance_method is supported。A:SINDI算法仅支持InnerProduct距离度量。请将distance_method修改为InnerProduct。如需使用Cosine距离,请对稀疏向量进行归一化处理后使用InnerProduct。
-
Q:报错
If property_key is 'proxima_vectors', only Graph algorithm is supported。A:稀疏向量索引不支持使用proxima_vectors属性,请使用vectors属性创建索引。
-
Q:稀疏向量写入时报错,提示索引值超出范围。
A:稀疏向量文本格式中的索引值(1-based)必须小于term_id_limit参数值。请检查数据中的最大索引值,并在创建索引时设置足够大的term_id_limit。例如,若数据中最大索引值为500000,则term_id_limit需大于500000。
-
Q:稀疏向量索引是否支持extra_columns?
A:不支持。SINDI算法当前不支持extra_columns参数,请勿在builder_params中配置该参数。
-
Q:如何判断查询是否命中了稀疏向量索引?
A:使用EXPLAIN ANALYZE查看执行计划。如果计划中出现Vector Filter关键字,则表示命中了稀疏向量索引。如果使用inner_product_distance函数(精确检索),执行计划显示Seq Scan,表示未使用索引。