稠密向量索引
本文介绍了 seekdb 如何创建、搜索、维护和删除稠密向量索引。
索引类型
seekdb 支持的稠密向量索引类型及其具体说明如下:
| 索引类型 | 描述 | 适用场景 |
|---|---|---|
| HNSW | 索引列最大维度为 4096。HNSW 索引是内存索引,需要完整载入内存,支持 DML 和实时搜索。 | |
| HNSW_SQ | HNSW_SQ 索引提供了和 HNSW 索引相近的构建速度,搜索性能,召回率,但总的内存使用降低到原本的 1/2~1/3。 | 对性能和召回率有较高要求的场景。 |
| HNSW_BQ | HNSW_BQ 索引的召回率略低于 HNSW 索引,但显著减少了内存占用。BQ 量化压缩算法(Rabitq)能将向量压缩至原大小的 1/32,随着向量维度增加,HNSW_BQ 索引的内存优化效果更明显。 | |
| IVF | 基于数据库表实现的 IVF 索引,可不占用常驻内存。 | 对性能要求不高,但数据量较大,成本敏感的场景。 |
| IVF_PQ | 基于数据库表实现的 IVF_PQ 索引,可不占用常驻内存。在 IVF 基础上应用了 PQ 量化技术,索引的召回率略低于 IVF 索引,性能高于 IVF 索引,同时 PQ 量化压缩算法普遍场景下能将向量压缩至原大小的 1/16 ~ 1/32。 | 对性能要求不高,但数据量较大,成本敏感的场景。 |
| IVF_SQ(实验特性) | 基于数据库表实现的 IVF_SQ 索引,可不占用常驻内存。在 IVF 基础上应用了 SQ 量化技术,索引的召回率略低于 IVF 索引,性能高于 IVF 索引,同时 SQ 量化压缩算法普遍场景下能将向量压缩至原大小的 1/3 ~ 1/4。 | 对性能要求不高,但数据量较大,成本敏感的场景。 |
一些其他说明:
- 稠密向量索引支持 L2、内积(IP)、余弦距离作为索引距离算法。
- 向量索引搜索支持调用部分距离函数,具体请参见 使用 SQL 函数。
- 支持带有过滤条件的向量搜索。过滤条件可以是标量类型的条件,可以是空间关系,如 ST_Intersects 等。暂不支持多值索引/全文索引/全局索引作为预过滤器。
- 支持同表创建向量索引和全文索引。
- 向量索引对 Offline DDL 的支持情况请见Offline DDL。
限制如下:
- 对于 V1.0.0 版本,暂不支持创建列存向量索引。
索引内存估算与实际占用查询
支持通过 DBMS_VECTOR 系统包进行索引内存估算:
- 未建表时,通过 INDEX_VECTOR_MEMORY_ADVISOR 过程估算索引内存。
- 已建表且插入数据时, 通过 INDEX_VECTOR_MEMORY_ESTIMATE 过程分析索引内存。
向量索引内存估算会返回两项信息:创建向量索引所需的最少内存配置,以及 HNSW_SQ 和 IVF 索引创建完成后的实际内存占用情况。
我们还提供了配置项 load_vector_index_on_follower 来控制 follower 角色是否自动加载内存向量索引。语法和示例请参见load_vector_index_on_follower。如果不需要弱读,可将此配置项关闭以减少向量索引占用的内存。
创建语法及说明
seekdb 向量索引的创建支持在建表时创建和后建两种方式。创建时需要注意:
- 创建向量索引必须带有
VECTOR关键字。 - 后建索引的参数和说明与建表时创建索引一致。
- 如果数据量较大,建议先写完数据,再创建索引,以获得最佳搜索性能。
- HNSW_SQ/IVF/IVF_SQ/IVF_PQ 索引均建议在写入数据后再创建索引,并在写入较多增量数据后进行索引重建。每个索引具体的创建说明见下文具体示例。
tab HNSW/HNSW_SQ/HNSW_BQ
建表时创建索引语法:
CREATE TABLE table_name (
column_name1 data_type1,
column_name2 data_type2,
...,
VECTOR INDEX index_name (column_name) WITH (param1=value1, param2=value2, ...)
);
后建索引语法:
-- 后建索引支持设置并行度,以提升索引构建性能,并行度最大设置不超过 CPU 核数 * 2
CREATE [/*+ paralell $value*/] VECTOR INDEX index_name ON table_name(column_name) WITH (param1=value1, param2=value2, ...);
param 参数说明:
| 参数 | 默认值 | 取值范围 | 是否必填 | 说明 | 备注 |
|---|---|---|---|---|---|
| distance | l2/inner_product/cosine | 是 | 指定向量距离算法类型。 | l2 表示欧氏距离,inner_product 表示内积距离,cosine 表示余弦距离。 | |
| type | 目前支持 hnsw / hnsw_sq/ hnsw_bq。 | 是 | 指定索引类型。 | ||
| lib | vsag | vsag | 否 | 指定向量索引库类型。 | 目前仅支持 VSAG 向量库。 |
| m | 16 | [5,128] | 否 | 每个节点的最大邻居数。 | 值越大,索引构建越慢,搜索性能越好。 |
| ef_construction | 200 | [5,1000] | 否 | 构建索引时的候选集大小。 | 值越大,索引构建越慢,索引质量越好。ef_construction 必须大于 m。 |
| ef_search | 64 | [1,1000] | 否 | 搜索时的候选集大小。 | 值越大,搜索越慢,召回率越高。 |
| extra_info_max_size | 0 | [0,16384] | 否 | 设置每个主键信息的最大大小(单位:字节)。将表的主键存储在索引中,以加快搜索速度。 | 0:不存储主键信息。1:强制存储主键信息,忽略大小限制。此时表的主键类型(详见下文)必须为支持的类型。大于 1:设置主键信息的最大大小(单位:字节)。此时,需要满足以下条件:
|
| refine_k | 4.0 | [1.0,1000.0] | 否 | 注意该参数从 V1.0.0 版本开始支持,仅在创建 HNSW_BQ 索引时可指定。 | 该参数可以在创建索引时设置,也可以在搜索时指定:
|
| refine_type | sq8 注意如果数据库是从旧版本升级到 V1.0.0 版本,则该参数默认值为 fp32。 | sq8/fp32 | 否 | 注意该参数从 V1.0.0 版本开始支持,仅在创建 HNSW_BQ 索引时可指定。 | 该值通过降低索引构建时的内存开销和索引构建时间来提高效率,但可能会影响召回率。 |
| bq_bits_query | 32 | 0/4/32 | 否 | 注意该参数从 V1.0.0 版本开始支持,仅在创建 HNSW_BQ 索引时可指定。 | 该值通过降低索引构建时的内存开销和索引构建时间来提高效率,但可能会影响召回率。 |
| bq_use_fht | true 注意如果数据库是从旧版本升级到 V1.0.0 版本,则该参数默认值为 false。 | true/false | 否 | 注意该参数从 V1.0.0 版本开始支持,仅在创建 HNSW_BQ 索引时可指定。 |
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
tab IVF/IVF_SQ(实验特性)/IVF_PQ
建表时创建索引语法:
CREATE TABLE table_name (
column_name1 data_type1,
column_name2 data_type2,
...,
VECTOR INDEX index_name (column_name) WITH (param1=value1, param2=value2, ...)
);
后建索引语法:
-- 后建索引支持设置并行度,以提升索引构建性能,并行度最大设置不超过 CPU 核 数 * 2
CREATE [/*+ paralell $value*/] VECTOR INDEX index_name ON table_name(column_name) WITH (param1=value1, param2=value2, ...);
param 参数说明:
| 参数 | 默认值 | 取值范围 | 是否必填 | 说明 | 备注 |
|---|---|---|---|---|---|
| distance | l2/inner_product/cosine | 是 | 指定向量距离算法类型。 | l2 表示欧氏距离,inner_product 表示内积距离,cosine 表示余弦距离。 | |
| type | ivf_flat/ivf_sq8/ivf_pq | 是 | 指定 IVF 索引类型。 | ||
| lib | ob | ob | 否 | 指定向量索引库类型。 | |
| nlist | 128 | [1,65536] | 否 | 聚类中心的个数。 | |
| sample_per_nlist | 256 | [1,int64_max] | 是 | 每个聚类中心的取样的数据量,后建索引中使用。 | |
| nbits | 8 | [1,24] | 否 | 指定量化位数。 该参数从 V1.0.0 版本开始支持,仅在创建 IVF_PQ 索引时可指定。 | 建议取值为 8,建议取值范围为 [8,10]。该值越大,量化精度越高,搜索准确率越高,同时搜索性能会受到影响。 |
| m | 无默认值,必须指定 | [1,65536] | 是 | 指定量化后的向量维度。 该参数从 V1.0.0 版本开始支持,仅在创建 IVF_PQ 索引时可指定。 | 该值越大,索引构建越慢,搜索准确率越高,同时搜索性能会受到影响。 |
搜索语法及说明
向量索引搜索是一种近似最近邻搜索,并不保证 100% 的结果正确。相应的向量搜索准确率的指标是召回率,例如在查 10 个最近邻时,如果可以稳定返回 9 个正确的结果,那么召回率就是 90%。召回率说明如下:
- 召回率受构建参数和搜索参数的影响。
- 索引搜索参数在建索引时指定,之后不可修改。但可通过 session 变量设置:HNSW/HNSW_SQ/HNSW_BQ 索引通过
ob_hnsw_ef_search设置,IVF 索引通过ob_ivf_nprobes设置。如果设置了 session 变量,会优先使用它的值。具体设置方式请参见 ob_hnsw_ef_search和 ob_ivf_nprobes。
稠密向量索引具体如下:
SELECT ... FROM $table_name ORDER BY $distance_function($column_name, $vector_expr) [APPROXIMATE|APPROX] LIMIT $num (OFFSET $num);
搜索使用说明如下:
-
搜索语法要求:
- 必须指定
APPROXIMATE/APPROX关键字,搜索才会使用向量索引而非全表扫描 。 - 必须包含
ORDER BY和LIMIT子句。 ORDER BY只支持单个向量条件。LIMIT + OFFSET的取值范围为(0, 16384]。
- 必须指定
-
距离函数使用规则:
- 指定
APPROXIMATE/APPROX,调用当前版本支持的距离函数,且与向量索引算法匹配,搜索会使用向量索引。 - 指定
APPROXIMATE/APPROX,距离函数与向量索引算法不匹配,搜索不会使用向量索引,但也不会报错。 - 指定
APPROXIMATE/APPROX,如果距离函数为当前版本不支持的距离函数,搜索不会使用向量索引,且会报错。 - 未指定
APPROXIMATE/APPROX,调用当前版本支持的距离函数,搜索不会使用向量索引,但也不会报错。
- 指定
-
其他说明:
WHERE条件会作为向量索引搜索后的过滤条件。- 不指定
LIMIT子句会报错。