跳到主要内容

HNSW 系列索引

本文档介绍了 seekdb 的稠密索引 HNSW 系列索引的创建、搜索、删除语法说明及示例。

索引语法及说明

创建

HNSW 系列索引包含 HNSW、HNSW_SQ 和 HNSW_BQ 三种索引,其创建支持在建表时创建后建两种方式。创建时需要注意:

  • 创建向量索引必须带有 VECTOR 关键字。
  • 后建索引的参数和说明与建表时创建索引一致。
  • 如果数据量较大,建议先写完数据,再创建索引,以获得最佳搜索性能。
  • HNSW_SQ 索引建议在写入数据后再创建索引,并在写入较多增量数据后进行索引重建。每个索引具体的创建说明见下文具体示例。
  • 创建 HNSW 索引时,索引名长度暂不支持超过 25 个字符,否则可能因为索引辅助表名长度超过 index_name 限制导致异常。未来版本会支持更长的索引名。
  • 建议在堆表上创建 HNSW 系列索引,以获得最佳搜索性能。

建表时创建

语法如下:

CREATE TABLE table_name (
column_name1 data_type1,
column_name2 VECTOR(dim),
...,
VECTOR INDEX index_name (column_name2) WITH (param1=value1, param2=value2, ...)
);

后建索引

语法如下:

-- 后建索引支持设置并行度,以提升索引构建性能,并行度最大设置不超过 CPU 核数 * 2
CREATE [/*+ paralell $value*/] VECTOR INDEX index_name ON table_name(column_name2) WITH (param1=value1, param2=value2, ...);

param 参数说明:

参数默认值取值范围是否必填说明备注
distancel2/inner_product/cosine指定向量距离算法类型。l2 表示欧氏距离,inner_product 表示内积距离,cosine 表示余弦距离。
type目前支持 hnsw / hnsw_sq/ hnsw_bq指定索引类型。
libvsagvsag指定向量索引库类型。目前仅支持 VSAG 向量库。
m16[5,128]每个节点的最大邻居数。值越大,索引构建越慢,搜索性能越好。
ef_construction200[5,1000]构建索引时的候选集大小。值越大,索引构建越慢,索引质量越好。ef_construction 必须大于 m
ef_search64[1,1000]搜索时的候选集大小。值越大,搜索越慢,召回率越高。
extra_info_max_size0[0,16384]设置每个主键信息的最大大小(单位:字节)。将表的主键存储在索引中,以加快搜索速度。0:不存储主键信息。
1:强制存储主键信息,忽略大小限制。此时表的主键类型(详见下文)必须为支持的类型。
大于 1:设置主键信息的最大大小(单位:字节)。此时,需要满足以下条件:
  • 主键信息的大小(计算方法见下文)必须小于设置的大小限制。
  • 表的主键类型必须是支持的类型。
  • 不是无主键表。
refine_k4.0[1.0,1000.0]该参数仅在创建 HNSW_BQ 索引时可指定。
该参数为浮点数类型,用于调整量化向量索引的重排比例。
该参数可以在创建索引时设置,也可以在搜索时指定:
  • 如果搜索时没有设置,则使用创建索引时的值;
  • 如果搜索时设置了,则使用搜索时设置的值。
refine_typesq8sq8/fp32该参数仅在创建 HNSW_BQ 索引时可指定。
用于设置量化向量索引的构建精度。
该值通过降低索引构建时的内存开销和索引构建时间来提高效率,但可能会影响召回率。
bq_bits_query320/4/32该参数仅在创建 HNSW_BQ 索引时可指定。
用于设置量化向量索引的搜索精度,单位为 bit。
该值通过降低索引构建时的内存开销和索引构建时间来提高效率,但可能会影响召回率。
bq_use_fhttruetrue/false该参数仅在创建 HNSW_BQ 索引时可指定。
用于设置是否使用 FHT 进行搜索。FHT(Fast Hadamard Transform)是一种用于加速向量内积计算的算法。

extra_info_max_size 支持的主键类型包括:

主键信息的大小计算方法:

SET @table_name = 'test'; -- 替换为要查询的 table_name
SELECT
CASE
WHEN COUNT(*) <> COUNT(result_value) THEN 'not support'
ELSE COALESCE(SUM(result_value), 'not support')
END AS extra_info_size
FROM (
SELECT
CASE
WHEN vdt.data_type_class IN (1, 2, 3, 4, 6, 8, 9, 14, 27, 28) THEN 8 -- 为数值类型 extra_info_size += 8
WHEN oc.data_type = 22 THEN oc.data_length -- 为 varchar 类型 extra_info_size += data_length
ELSE NULL -- 其他类型不支持
END AS result_value
FROM
oceanbase.__all_column oc
JOIN
oceanbase.__all_virtual_data_type vdt
ON
oc.data_type = vdt.data_type
WHERE
oc.rowkey_position != 0
AND oc.table_id = (SELECT table_id FROM oceanbase.__all_table WHERE table_name = @table_name)
) AS result_table;
-- 计算结果为 8 byte

搜索

HNSW 系列索引的搜索是一种近似最近邻(ANN)搜索,不保证 100% 的结果准确性。衡量其准确率的指标是召回率,例如在查询 10 个最近邻时,若能稳定返回 9 个正确结果,则召回率为 90%。

SELECT ... FROM table_name 
ORDER BY distance_function(column_name, vector_expr) [APPROXIMATE|APPROX]
LIMIT num (OFFSET num);

搜索语法要求:

  • 必须指定 APPROXIMATE/APPROX 关键字,搜索才会使用向量索引而非全表扫描。
  • 必须包含 ORDER BYLIMIT 子句。
  • ORDER BY 只支持单个向量条件。
  • LIMIT + OFFSET 的取值范围为 (0, 16384]
  • 不指定 LIMIT 子句会报错。

距离函数使用规则:

  • 指定 APPROXIMATE/APPROX,调用当前版本支持的距离函数,且与向量索引算法匹配,搜索会使用向量索引。
  • 指定 APPROXIMATE/APPROX,距离函数与向量索引算法不匹配,搜索不会使用向量索引,但也不会报错。
  • 指定 APPROXIMATE/APPROX,如果距离函数为当前版本不支持的距离函数,搜索不会使用向量索引,且会报错。
  • 未指定 APPROXIMATE/APPROX,调用当前版本支持的距离函数,搜索不会使用向量索引,但也不会报错。

其他说明:

  • WHERE 条件会作为向量索引搜索的过滤条件。
  • 召回率受构建参数和搜索参数的影响。
  • 索引搜索参数可以在创建索引时进行设置。如果在索引创建完成后需要调整,可以通过 DBMS_VECTOR.REBUILD_INDEX 修改表级属性,也可以在查询时通过指定查询级别参数 ef_search 进行调整。

删除

删除向量索引的语法如下:

DROP INDEX index_name ON table_name;

创建、搜索和删除示例

建表时创建

HNSW 示例

创建测试表。

CREATE TABLE t1(c1 INT, c0 INT, c2 VECTOR(10), c3 VECTOR(10), PRIMARY KEY(c1), VECTOR INDEX idx1(c2) WITH (distance=l2, type=hnsw, lib=vsag),  VECTOR INDEX idx2(c3) WITH (distance=l2, type=hnsw, lib=vsag));

写入测试数据。

INSERT INTO t1 VALUES(1, 1,'[0.203846,0.205289,0.880265,0.824340,0.615737,0.496899,0.983632,0.865571,0.248373,0.542833]', '[0.203846,0.205289,0.880265,0.824340,0.615737,0.496899,0.983632,0.865571,0.248373,0.542833]');
INSERT INTO t1 VALUES(2, 2, '[0.735541,0.670776,0.903237,0.447223,0.232028,0.659316,0.765661,0.226980,0.579658,0.933939]', '[0.213846,0.205289,0.880265,0.824340,0.615737,0.496899,0.983632,0.865571,0.248373,0.542833]');
INSERT INTO t1 VALUES(3, 3, '[0.327936,0.048756,0.084670,0.389642,0.970982,0.370915,0.181664,0.940780,0.013905,0.628127]', '[0.223846,0.205289,0.880265,0.824340,0.615737,0.496899,0.983632,0.865571,0.248373,0.542833]');

使用近似最近邻搜索。

SELECT * FROM t1 ORDER BY l2_distance(c2, [0.712338,0.603321,0.133444,0.428146,0.876387,0.763293,0.408760,0.765300,0.560072,0.900498]) APPROXIMATE LIMIT 1;

返回结果如下:

+----+------+-------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------+
| c1 | c0 | c2 | c3 |
+----+------+-------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------+
| 3 | 3 | [0.327936,0.048756,0.08467,0.389642,0.970982,0.370915,0.181664,0.94078,0.013905,0.628127] | [0.223846,0.205289,0.880265,0.82434,0.615737,0.496899,0.983632,0.865571,0.248373,0.542833] |
+----+------+-------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------+
1 row in set
HNSW_SQ 示例
CREATE TABLE t2 (c1 INT AUTO_INCREMENT, c2 VECTOR(3), PRIMARY KEY(c1), VECTOR INDEX idx1(c2) WITH (distance=l2, type=hnsw_sq, lib=vsag));
HNSW_BQ 示例
CREATE TABLE t3 (c1 INT AUTO_INCREMENT, c2 VECTOR(3), PRIMARY KEY(c1), VECTOR INDEX idx3(c2) WITH (distance=l2, type=hnsw_bq, lib=vsag));

HNSW_BQ distance 参数支持 l2cosine

后建

HNSW 示例

创建测试表。

CREATE TABLE vec_table_hnsw (id INT, c2 VECTOR(10));

创建 HNSW 索引。

CREATE VECTOR INDEX vec_idx1 ON vec_table_hnsw(c2) WITH (distance=l2, type=hnsw);

查看创建的表。

SHOW CREATE TABLE vec_table_hnsw;

返回结果如下:

+-----------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+-----------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| vec_table_hnsw | CREATE TABLE `vec_table_hnsw` (
`id` int(11) DEFAULT NULL,
`c2` VECTOR(10) DEFAULT NULL,
VECTOR KEY `vec_idx1` (`c2`) WITH (DISTANCE=L2, TYPE=HNSW, LIB=VSAG, M=16, EF_CONSTRUCTION=200, EF_SEARCH=64) BLOCK_SIZE 16384
) DEFAULT CHARSET = utf8mb4 ROW_FORMAT = DYNAMIC COMPRESSION = 'zstd_1.3.8' REPLICA_NUM = 2 BLOCK_SIZE = 16384 USE_BLOOM_FILTER = FALSE TABLET_SIZE = 134217728 PCTFREE = 0 |
+-----------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set

查看创建的索引。

SHOW INDEX FROM vec_table_hnsw;

返回结果如下:

+-----------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+-----------+---------------+---------+------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment | Visible | Expression |
+-----------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+-----------+---------------+---------+------------+
| vec_table | 1 | vec_idx1 | 1 | c2 | A | NULL | NULL | NULL | YES | VECTOR | available | | YES | NULL |
+-----------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+-----------+---------------+---------+------------+
1 row in set

HNSW_SQ 示例

创建测试表。

CREATE TABLE vec_table_hnsw_sq (c1 INT AUTO_INCREMENT, c2 VECTOR(3), PRIMARY KEY(c1));

创建 HNSW_SQ 索引。

CREATE VECTOR INDEX vec_idx2 ON vec_table_hnsw_sq(c2) WITH (distance=l2, type=hnsw_sq, lib=vsag, m=16, ef_construction = 200);
HNSW_BQ 示例
CREATE VECTOR INDEX vec_idx3 ON vec_table_hnsw_bq(c2) WITH (distance=l2, type=hnsw_bq, lib=vsag, m=16, ef_construction = 200);

HNSW_BQ 索引 distance 参数支持 l2cosine

删除

DROP INDEX vec_idx1 ON vec_table;

查看删除的索引。

SHOW INDEX FROM vec_table;

返回结果如下:

Empty set

相关文档