HybridANN索引
原理介绍
HybridAnn索引允许在向量索引基础上额外增加对标量条件的过滤功能。在构建索引时将需要支持的标量放入索引构建目标中。
HybridAnn采用了改良后的graph_index作为向量检索索引,令HybridANN也继承了graph_index的优势——更高的召回率,更低的内存占用和更短的索引构建耗时。
注意事项
- 构建HybridANN索引时,该索引第一列必须为向量类型floatvector,作为向量检索中的向量查询目标;其余列为非向量的其他标量数据,比如数值,时间,枚举类型等。具体支持的标量类型可以通过如下语句查看:
SELECT DISTINCT typname FROM pg_am, pg_amop, pg_type WHERE pg_type.oid = amoplefttype AND pg_am.oid = amopmethod AND amname = 'hybridann';
- 单个HybridANN索引最多能包含31个标量字段。
- 当增删业务较少时,可以适当放宽向标联合索引的数量限制。具体数量由同时被使用到的索引数量,增删业务量,机器规格等综合考虑。
- 向标联合索引的创建和查询资源占用以及对增删业务的影响高于其他索引类型。
- 与B+树索引要求相同,字符匹配、数组操作、表达式等B+树不支持的条件不能使用向标联合索引。
- 暂不支持在空表上创建HybridANN索引。
- 向标联合索引查询不支持针对标量字段执行 IS NULL 或 IS NOT NULL 查询, 也不支持order by标量字段走向标联合索引查询。
- 如果向标联合检索、纯向量/标量检索未按照预期走索引,请参考向量查询不走索引中介绍的内容进行排查,确认查询是否满足走索引的条件。
索引参数
索引构建参数
参数名称 | 取值说明 | 参数描述 |
---|---|---|
m | 取值范围:2~100 默认值:16 |
每个顶点/节点与其最近邻居的最大连接数。 |
ef_construction | 取值范围:4~1000 默认值:64 |
控制索引构建过程中使用的候选列表的大小。 |
parallel_workers | 取值范围:0~64 默认值:0 |
并行构建参数,构建索引并行计算线程数。 |
fillfactor | 取值范围:10~100 默认值:90 |
构建索引时 B+树叶子节点的百分比负载度,参数逻辑同 B+树索引同名参数。不推荐更改。 |
vec_index_magnitudes_offset | 取值范围:以冒号分隔的正整数列表。共5层。参数类型为字符串,格式为 N1[:N2[:N3[...]]。 默认值:20000:100000:500000:2500000:12500000 |
会话级参数,触发构建内部向量索引的数据量级,提供的量级越多,向量索引构建的越精细,查询时匹配度越高,但索引数量也越多,构建时间越长。 |
graph_magnitude_threshold | 取值范围:1-10'000'000'000。 默认值20000 |
图索引构建阈值,大于等于该数值的向量索引使用图索引。 |
索引构建GUC参数
参数名称 | 取值说明 | 参数描述 |
---|---|---|
max_vector_indexer_worker_threads | 取值范围:2~64 默认值:16 |
实例级参数 max_vector_indexer_worker_threads 用于控制后台用于构建向量索引的线程数量上限。构建任务由系统自动调度分发,合理配置该参数可以有效加速大规模向量数据的索引构建过程。 |
GUC 查询参数
参数名称 | 取值说明 | 参数描述 |
---|---|---|
hnsw_ef_search | 取值范围:1~32767 默认值:100 |
会话级参数,表示索引搜索过程中将考虑的最大候选邻居数。数值越高召回越精确,检索越慢。 实际生效值是top-k(查询的limit n)和hnsw_ef_search中更大的值。 |
hybrid_query_ivf_probes_factor | 取值范围:1~100 默认值:3 |
会话级参数。 该参数控制选择率小的查询搜索范围,调参逻辑等同于 ivf_probes ,根据召回率要求修改。 |
max_vector_indexer_query_threads | 取值范围:整型,[0,256] 默认值:0,表示关闭向量并行检索。 |
同时进行向量检索的最大并行线程数。 |
使用建议
- 建议将所有需要查询的数据提前插入表中,最后再建立索引;如果决定先建立索引再导入数据,在数据导入完成后需要重建索引。
- 当需要提升索引构建速度, 可以适当增大 parallel_workers,建议设置为机器 CPU 核数的 75%,最大值 64。
- 当需要提升召回率时, 可适当增大 ef_search 和 hybrid_query_ivf_probes_factor,参数越大则召回率越高,查询变慢。
- 当前标量支持条件与系统默认索引 B+ 树一致。
- 使用 explain 语句确定语句是否使用向标混合索引以及预计的具体执行。
使用示例
- 数据准备:创建用于生成随机向量的函数。
CREATE OR REPLACE FUNCTION random_array(dim integer,min_value int, max_value int) RETURNS text AS $$ SELECT REGEXP_REPLACE(REGEXP_REPLACE(array_agg(round(random()* (max_value - min_value + 1) + min_value,3))::text,'{','['),'}',']') FROM generate_series(1, dim); $$ LANGUAGE SQL VOLATILE COST 1;
- 创建测试表并插入数据。
DROP TABLE t_1194690; CREATE TABLE t_1194690(id BIGINT, v floatVECTOR(15)); INSERT INTO t_1194690 SELECT i, random_array(15,1,3)::floatvector(15) FROM generate_series(1, 10000) AS i;
- 创建索引。注意把需要用到的标量放入索引创建内容中,将向量排在第一位。
- 按余弦距离构建索引,使用B+树挂载向量索引实现:
CREATE INDEX idx_1194690a ON t_1194690 USING hybridann(v floatvector_cosine_ops, id) WITH (parallel_workers=5);
- 按欧几里得距离构建索引,使用混合图索引实现(WITH设置参数也可省略,此时为默认值):
CREATE INDEX idx_1194690b ON t_1194690 USING hybridann(v floatvector_l2_ops, id) WITH (parallel_workers=5);
- 按余弦距离构建索引,使用B+树挂载向量索引实现:
- 设置查询参数(可选)。
set ef_search=10; set hybrid_query_ivf_probes_factor = 3;
- 向量标量混合检索:带有标量条件的余弦距离排序。
SELECT * FROM t_1194690 WHERE id BETWEEN 5000 AND 6000 ORDER BY v <=> '[1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0]'::floatvector LIMIT 10;
- 向量标量混合检索:带有标量条件的欧几里得距离排序。
SELECT * FROM t_1194690 WHERE id BETWEEN 2000 AND 4000 ORDER BY v <-> '[1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0]'::floatvector LIMIT 10;