使用MySQL协议进行向量检索

PolarDB MySQL通过内置的向量数据类型、距离函数和向量索引,支持以SQL语言进行高效的向量相似度检索。该功能适用于推荐系统、聊天机器人、图像检索等应用场景。向量计算能力集成于数据库内核中,支持ACID事务,并借助列存索引(IMCI)HNSW等算法,能够提供100%召回率的精确KNN检索以及高性能的近似ANN检索。

适用范围

使用本功能前,请确认您的集群版本需满足:内核版本为MySQL 8.0.2,且修订版本需为8.0.2.2.30及以上版本。

版本更新记录

不同内核版本支持的功能存在差异。建议升级至最新版本。

功能点

最低内核版本要求

说明

基础向量功能与HNSW索引算法。

8.0.2.2.30

提供向量检索的基础能力。

新增FAISS_HNSW_FLATFAISS_HNSW_PQ索引算法。

8.0.2.2.31

引入基于FAISS实现的索引算法。

修改或删除向量索引。

8.0.2.2.32

允许通过ALTER TABLE动态管理向量索引。

向量类型

类型定义

CREATE TABLEALTER TABLE语句中使用VECTOR(N)类型定义向量列。

  • N代表向量的维度,取值范围为116383。

  • 向量的每一维均为单精度浮点数(4字节)。

  • 向量类型仅支持与向量类型进行等值比较,禁止与其他任意类型进行比较。

  • 向量列不能作为主键、外键、唯一键或分区键。

示例

-- 以下示例表示在表t1中定义列v1的向量维度为4
CREATE TABLE t1 (id INT PRIMARY KEY, v1 VECTOR(4));
说明

如果定义维度超过16383,将返回错误Data size (xxx Bytes, xxx dimensions) exceeds VECTOR max (65532 Bytes, 16383 dimensions) for column: 'xxx'

类型转换

PolarDB提供STRING_TO_VECTORVECTOR_TO_STRING函数,用于在字符串格式和二进制格式之间转换。

字符串转二进制(STRING_TO_VECTOR

此函数用于将文本格式的向量转换为数据库内部的二进制格式。

  • 输入格式:由方括号[]包裹、英文逗号,分隔的浮点数序列,例如'[1.2, 3.4, 5.6]'

    说明

    如果输入格式错误的字符串,将返回错误Data cannot be converted to a valid vector: 'xxx'

  • 字节序说明:转换后的二进制数据采用小端字节序(Little-Endian)。例如,浮点数1.0的十六进制表示0x3F800000存入数据库后,其二进制HEX值为0000803F。在跨系统进行数据序列化时需注意此点。

示例

SELECT STRING_TO_VECTOR('[1,2,3,4]');
+-------------------------------+
| STRING_TO_VECTOR('[1,2,3,4]') |
+-------------------------------+
|   �?   @  @@  �@              |
+-------------------------------+
SELECT HEX(STRING_TO_VECTOR('[1,2,3,4]'));
+------------------------------------+
| HEX(STRING_TO_VECTOR('[1,2,3,4]')) |
+------------------------------------+
| 0000803F000000400000404000008040   |
+------------------------------------+

二进制转字符串(VECTOR_TO_STRING

此函数用于将数据库中存储的二进制向量数据转换为字符串格式。

输入格式:每4个字节对应向量中某一维的浮点数的Binary表示,采用小端字节序(Little-Endian)。例如,浮点数1.0的十六进制表示为0x3F800000,存入数据库后,其二进制HEX值为0000803F。在跨系统进行数据序列化时需注意此点。

说明

如果输入格式错误的Binary,将返回错误Data cannot be converted to a valid vector: ''

示例

SELECT VECTOR_TO_STRING(0x0000803F000000400000404000008040);
+------------------------------------------------------+
| VECTOR_TO_STRING(0x0000803F000000400000404000008040) |
+------------------------------------------------------+
| [1.00000e+00,2.00000e+00,3.00000e+00,4.00000e+00]    |
+------------------------------------------------------+

相关操作示例

创建包含向量列的新表

CREATE TABLE t1 (id INT PRIMARY KEY, v1 VECTOR(4));

将向量列添加到现有表中

ALTER TABLE t1 ADD COLUMN v1 VECTOR(4);

插入向量

  • 向量通过STRING_TO_VECTOR函数以字符串的形式插入。

    INSERT INTO t1 (id, v1) VALUES (1, STRING_TO_VECTOR('[1.0, 2.0, 3.0, 4.0]'));
  • 向量以Binary的形式插入。

    INSERT INTO t1 VALUES (2, 0x0000803F000000400000404000008040);

插入或更新向量

向量通过STRING_TO_VECTOR以字符串的形式插入或更新。

INSERT INTO t1 VALUES (1, STRING_TO_VECTOR('[1.0, 2.0, 3.0, 4.0]')) ON DUPLICATE KEY UPDATE v1 = STRING_TO_VECTOR('[1.0, 2.0, 3.0, 4.0]');

更新向量

向量通过STRING_TO_VECTOR以字符串的形式更新。同时,也支持直接以Binary的形式更新。

UPDATE t1 SET v1 = STRING_TO_VECTOR('[1.0, 2.0, 3.0, 4.0]') WHERE id = 1;

删除向量

向量通过STRING_TO_VECTOR以字符串的形式删除。同时,也支持直接以Binary的形式删除。

DELETE FROM t1 WHERE v1 = STRING_TO_VECTOR('[1.0, 2.0, 3.0, 4.0]');

使用向量索引

PolarDB通过在列的COMMENT中定义特殊格式的字符串来创建向量索引。

前置条件

在使用向量索引之前,需先添添加列存索引只读节点,并为该列或整个表创建列存索引。即只有列存索引只读节点才能构建向量索引,以支持向量检索。

创建向量索引

CREATE TABLEALTER TABLE时,通过修改列的COMMENT来定义向量索引。

语法说明

COMMENT 'imci_vector_index=向量索引算法(索引参数列表) [其他备注]'
  • imci_vector_index=:固定前缀,声明这是一个向量索引定义。

  • 向量索引算法:索引算法,如HNSWFAISS_HNSW_FLATFAISS_HNSW_PQ算法。

  • 索引参数列表:括号内为索引的构建参数。

    • 多个参数间可用空格、英文逗号或英文分号分隔。为避免混淆,建议统一使用英文逗号。

    • 单个参数写法为参数名=参数值参数名:参数值。例如:HNSW(metric=COSINE,max_degree=16,ef_construction=300)

    • 当所有参数都使用默认值时仍然需要指定圆括号。例如:COMMENT "imci_vector_index=HNSW() 其他备注信息"

索引算法

算法

适用场景

HNSW

基于VSAG实现,追求高精度,内存占用较大。

FAISS_HNSW_FLAT

基于FAISS实现,追求高精度,内存占用较大。

FAISS_HNSW_PQ

基于FAISS实现,通过乘积量化(PQ)压缩向量,降低内存占用,但会损失一定精度。

索引参数

参数

可用别名

适用算法

作用

可选值/范围

默认值

metric

distance

  • HNSW

  • FAISS_HNSW_FLAT

  • FAISS_HNSW_PQ

向量相似度度量。

  • COSINE(余弦距离)

  • INNER_PRODUCT(内积)

  • EUCLIDEAN(欧式距离)

说明

仅支持大写。

COSINE

max_degree

M

  • HNSW

  • FAISS_HNSW_FLAT

  • FAISS_HNSW_PQ

图中每个节点的最大连接数。

正整数。值越大,图越稠密,构建越慢,内存占用越高,但查询精度可能更高。建议范围16-64。

16

ef_construction

-

  • HNSW

  • FAISS_HNSW_FLAT

  • FAISS_HNSW_PQ

构建索引时搜索的邻居节点数量。

正整数。值越大,索引质量越高,但构建时间越长。建议设置为100-500。

200

pq_m

-

FAISS_HNSW_PQ

乘积量化(PQ)子空间的数量。

可整除维度的正整数。向量维度需能被pq_m整除。值越大,精度越高,但内存占用也越高。

1

pq_nbits

-

FAISS_HNSW_PQ

乘积量化(PQ)中每个子空间量化表示使用的bit数。

小于或等于24的正整数。通常设置为8,表示每个子空间有256个中心点。

8

示例1:创建表时定义向量索引

-- 方案一:为整个表开启列存,然后在v1列上定义向量索引
CREATE TABLE t1 (
    id INT PRIMARY KEY,
    v1 VECTOR(4) COMMENT 'imci_vector_index=HNSW(metric=COSINE, max_degree=16)'
) COMMENT 'COLUMNAR=1';

-- 方案二:仅为v1列开启列存和向量索引
CREATE TABLE t1 (
    id INT PRIMARY KEY,
    description TEXT,
    v1 VECTOR(4) COMMENT 'COLUMNAR=1, imci_vector_index=HNSW(metric=COSINE)'
);

示例2:为现有表添加向量索引

-- 假设现有表为t1
CREATE TABLE t1 (
    id int auto_increment PRIMARY KEY,
    v1 vector(4)
);

-- 方案一:添加表级列存索引同时修改VECTOR列备注信息指定向量索引算法及参数
ALTER TABLE t1 comment "COLUMNAR=1", MODIFY COLUMN v1 vector(4) COMMENT "imci_vector_index=HNSW(metric=COSINE,max_degree=16,ef_construction=300)";


-- 方案二:仅为v1列创建列存索引,列存索引初始化时会自动根据v1列上的备注信息创建向量索引
ALTER TABLE t1 MODIFY COLUMN v1 vector(4) COMMENT "COLUMNAR=1 imci_vector_index=HNSW(metric=COSINE,max_degree=16,ef_construction=300)";

参数说明

参数名

说明

imci_enable_inline_vector_index

是否允许创建向量索引。

  • ON(默认):开启后,列存索引只读节点会在创建列存索引时根据向量列的备注信息来创建向量索引。

  • OFF:关闭后,列存索引只读节点在创建列存索引时不再为向量列创建向量索引,关闭前创建的存量向量索引会继续构建但重启后不再加载和构建。

imci_vector_index_dump_rows_threshold

用于控制向量索引的增量写入大小。后台任务会定期检查当前向量索引快照位点与列存索引快照位点之间的增量。当增量行数超过该阈值时,后台任务将会提交新增数据行以追加到向量索引中。

  • 取值范围:1~4294967295。

  • 默认值:1000。

  • 单位:行数。

修改向量索引

说明

修订版本为8.0.2.2.32及以上版本支持通过修改向量类型的列上的备注信息来修改向量索引的算法和参数。

  • 修改向量索引算法。

    CREATE TABLE t1 (
        id int auto_increment PRIMARY KEY,
        v1 vector(4) COMMENT "imci_vector_index=HNSW(metric=COSINE,max_degree=16,ef_construction=300)"
    ) COMMENT 'COLUMNAR=1';
    
    -- 修改索引算法,将HNSW算法修改为基于FAISSHNSW算法
    ALTER TABLE t1 modify column v1 vector(4) COMMENT "imci_vector_index=FAISS_HNSW_FLAT(metric=COSINE,max_degree=16,ef_construction=300)";
  • 修改向量索引参数。

    CREATE TABLE t1 (
        id int auto_increment PRIMARY KEY,
        v1 vector(4) COMMENT "imci_vector_index=HNSW(metric=COSINE,max_degree=16,ef_construction=300)"
    ) COMMENT 'COLUMNAR=1';
    
    -- 修改索引参数,将HNSWmax_degree16修改为32
    ALTER TABLE t1 modify column v1 vector(4) COMMENT "imci_vector_index=HNSW(metric=COSINE,max_degree=32,ef_construction=300)";

删除向量索引

  • 删除列存索引时删除向量索引。

    CREATE TABLE t1 (
        id int auto_increment PRIMARY KEY,
        v1 vector(4) COMMENT "imci_vector_index=HNSW(metric=COSINE,max_degree=16,ef_construction=300)"
    ) COMMENT 'COLUMNAR=1';
    
    -- 向量索引不能独立于列存索引存在,会被级联删除
    ALTER TABLE t1 COMMENT 'COLUMNAR=0';
  • 仅删除向量索引。

    说明

    修订版本为8.0.2.2.32及以上版本支持通过删除向量类型的列上的备注信息来删除向量索引。

    CREATE TABLE t1 (
        id int auto_increment PRIMARY KEY,
        v1 vector(4) COMMENT "imci_vector_index=HNSW(metric=COSINE,max_degree=16,ef_construction=300)"
    ) COMMENT 'COLUMNAR=1';
    
    -- 通过删除向量类型的列上的备注信息来删除向量索引
    ALTER TABLE t1 modify column v1 vector(4) COMMENT "";

向量查询

近似最近邻(ANN)检索

近似最近邻(ANN)检索基于向量索引加速查询。

使用限制

优化器仅在识别到特定SQL模式时才使用向量索引,查询需同时满足以下所有条件:

  • 需同时包含ORDER BYLIMIT子句。

  • ORDER BY的第一个表达式需为DISTANCE(...)

  • ORDER BY DISTANCE(...)的排序方向是ASC

  • DISTANCE(...)表达式中的字段必须存在可用的向量索引

  • DISTANCE(...)表达式中的距离参数metric必须与创建向量索引时使用的距离参数metric保持一致。例如,如果向量索引采用COSINE距离构建,则DISTANCEE(...)也必须指定COSINE

  • 若包含JOIN,执行计划必须采用右深树(Right Deep Join Tree)结构,且DISTANCE(...)表达式中引用的字段必须来自JOIN的驱动表。

  • 查询中不能包含GROUP BY子句。如需聚合,应在子查询中完成向量检索。

启用ANN检索的步骤

  1. 启用向量索引加速功能
    在会话中执行以下命令,允许优化器使用向量索引。

    SET imci_enable_vector_search = ON;
  2. 强制查询使用列存执行计划
    为确保查询能访问到构建在列存上的向量索引,需强制查询走列存路径。

    SET cost_threshold_for_imci = 0;
    重要

    SET cost_threshold_for_imci = 0;是一个会话级别的设置,为了强制将该会话中的所有查询使用列存索引。这可能导致本应在行存上高效运行的查询(例如,通过主键进行的点查)性能下降。因此,建议仅在执行向量检索的会话中使用此设置,切勿将其设置为全局参数。

  3. 编写符合ANN触发条件的查询
    执行满足约束条件SQL即可使用向量索引完成近似最近邻检索。

    -- 查找Top 5最相似的记录
    SELECT id, v1
    FROM t1
    WHERE category_id = 123 -- 可加附件条件
    ORDER BY DISTANCE(v1, STRING_TO_VECTOR('[...]'), 'COSINE') ASC
    LIMIT 5;

    不合规查询的修正(以GROUP BY为例):

    -- 错误写法:GROUP BY 与 ORDER BY DISTANCE() 冲突
    -- SELECT category_id, COUNT(*) FROM t1 GROUP BY category_id ORDER BY DISTANCE(v1, STRING_TO_VECTOR('[...]'), 'COSINE') ASC LIMIT 5;
    
    -- 正确写法:先用子查询完成ANN检索,再对结果进行聚合
    SELECT category_id, COUNT(*)
    FROM (
        SELECT id, category_id
        FROM t1
        ORDER BY DISTANCE(v1, STRING_TO_VECTOR('[...]'), 'COSINE') ASC
        LIMIT 100 -- 先召回100个最近邻
    ) AS nearest_neighbors
    GROUP BY category_id;
  4. 您可以通过EXPLAIN语句来判断在SQL语句中使用的向量索引加速近似最近邻检索功能是否生效。如果执行计划中包含Vector Search,则表示向量索引加速近似最近邻检索功能生效。

    EXPLAIN SELECT * FROM t1 ORDER BY DISTANCE(v1, STRING_TO_VECTOR('[1.2, 2.3, 3.4, 4.5]'), 'COSINE') LIMIT 2;

    输出示例:

    +----+---------------------------+------+--------+--------+---------------------------------------------------------------------------------------+
    | ID | Operator                  | Name | E-Rows | E-Cost | Extra Info                                                                            |
    +----+---------------------------+------+--------+--------+---------------------------------------------------------------------------------------+
    |  1 | Select Statement          |      |        |        | IMCI Execution Plan (max_dop = 2, max_query_mem = 429496729)                          |
    |  2 | └─Compute Scalar          |      | 2      | 0.00   |                                                                                       |
    |  3 |   └─Limit                 |      | 2      | 0.00   | Offset=0 Limit=2                                                                      |
    |  4 |     └─Sort                |      | 2      | 0.00   | Sort Key: VECTOR_DISTANCE(t1.v1,"[1.200000,2.300000,3.400000,4.500000]","COSINE") ASC |
    |  5 |       └─Vector Search     | t1   | 2      | 0.00   |                                                                                       |
    +----+---------------------------+------+--------+--------+---------------------------------------------------------------------------------------+

参数说明

参数名称

参数说明

imci_enable_vector_search

使用向量索引加速近似最近邻(ANN)检索的控制开关。

  • ON(默认):开启使用向量索引加速近似最近邻(ANN)检索功能。

  • OFF:关闭使用向量索引加速近似最近邻(ANN)检索功能。

imci_hnswpq_k_factor

当向量索引使用FAISS_HNSW_PQ算法时,向量检索的扩召回倍数。

  • 取值范围:1~UINT32_MAX.

  • 默认值:1。

  • 单位:倍数。

说明

在进行向量查询以召回K个近似最近邻(ANN)时,执行器将从HNSW PQ索引中召回K * imci_hnswpq_k_factor个结果,然后对这些结果使用原始向量进行精确排序,最终按顺序返回K个结果。

查看向量

SELECT VECTOR_TO_STRING(v1) FROM t1;

距离计算

通过DISTANCE函数可以采用指定方式计算两个向量之间的相似度。

DISTANCE(vector1, vector2, '<metric>')

metric参数说明

参数

说明

COSINE

余弦相似度。衡量两个向量之间的方向相似性,结果为两个向量夹角的余弦值。越小越相似。

EUCLIDEAN

欧式距离。衡量两个向量或点在欧几里得空间中的直线距离。越小越相似。

DOT

点积。两个向量对应分量相乘后再相加的结果。越小越相似。

示例

SELECT DISTANCE(v1, STRING_TO_VECTOR('[1.2,2.3,3.4,4.5]'), 'COSINE') FROM t1;

精确最近邻(KNN)检索

精确检索会遍历所有数据计算距离,保证100%的召回率。它不依赖向量索引,适用于数据量较小的场景。

-- 查找与目标最相似的10条记录SELECT id, VECTOR_TO_STRING(v1)FROM t1
ORDER BY DISTANCE(v1, STRING_TO_VECTOR('[...]'), 'COSINE')LIMIT 10;

示例

SELECT id, VECTOR_TO_STRING(v1) FROM t1 ORDER BY DISTANCE(v1, STRING_TO_VECTOR('[1.2,2.3,3.4,4.5]'), 'COSINE') LIMIT 1;

包含谓词的向量查询

您可以使用额外的列作为谓词,来过滤向量查询结果。例如:

SELECT * FROM t1 WHERE id < 10 ORDER BY DISTANCE(v1, STRING_TO_VECTOR('[1.2, 2.3, 3.4, 4.5]'), 'COSINE') LIMIT 2;

在使用包含谓词的SQL语句进行向量查询时,可以通过调整相关参数的值来控制向量索引召回和谓词过滤的先后顺序。

执行方式

向量检索通常伴随其他属性的过滤。优化器会根据过滤条件的选择性,智能选择执行策略:

  • 前置过滤(prefilter):当过滤条件能大幅减少数据量时(如匹配行数小于imci_vector_search_prefilter_rows,默认10000),系统将首先对全表进行谓词过滤,以获取匹配的记录,然后对这些记录进行排序,最终按顺序返回由LIMIT指定的数量的记录。

  • 后置过滤 (postfilter):当过滤条件选择性较差时(如匹配率高于imci_vector_search_filter_pct,默认20%),系统将首先应用向量索引进行结果召回,然后对召回的结果进行谓词过滤。如果过滤后的结果数量少于LIMIT指定的数量,则需重复上述过程。

  • 内联过滤(inline filter):如果优化器未选择前置过滤或后置过滤的执行方式,那么将选择使用内联过滤的方式执行。系统将首先通过谓词对全表进行过滤,利用匹配记录的RowID构建bitmap过滤器。随后,将采用向量索引进行召回。在向量索引的检索过程中,通过bitmap过滤器进行筛选,以确保返回的最相似记录满足谓词条件。

自适应执行优化

由于优化器对谓词过滤所匹配行数的预估可能存在偏差,导致执行方式的选择可能并非最优。因此,采用自适应执行机制,在执行过程中根据实际匹配行数动态切换执行方式。

在使用内联过滤(inline filter)方式执行包含谓词的向量查询时,如果在进行谓词过滤全表后,实际匹配的记录数量低于imci_vector_search_prefilter_rows,则会动态切换为前置过滤方式进行执行。

分区优化

向量查询通常包含租户ID或标签等谓词条件。针对这类查询,可以采用LIST DEFAULT HASH的分区方式,为数据量较大的租户或标签构建独立的LIST分区,而为其他租户或标签构建DEFAULT HASH分区。优化器能够识别这类查询,并依据分区裁剪的结果,为较大租户或标签的向量查询选择后置过滤的执行方式,而为其他租户的向量查询则使用前置过滤或内联过滤的执行方式,尽可能为不同规模的租户或标签选择最优的执行方式。

参数说明

参数名称

参数说明

imci_vector_search_filter_pct

当谓词过滤的预估选择率大于或等于该参数值时,优先使用向量索引召回。

  • 取值范围:0~100。

  • 默认值:20。

  • 单位:%。

当前默认值表示,当谓词的预估选择率大于或等于20%时,系统将优先使用向量索引进行召回,随后再进行谓词过滤以获得召回结果。

imci_enable_vector_search_inline_filter

包含谓词的向量查询使用内联过滤(inline filter)的控制开关。

  • OFF(默认):关闭。

  • ON:开启。

imci_vector_search_prefilter_rows

当谓词过滤的预估匹配行数小于该参数值时,优先采用谓词前置过滤的方式进行召回。

  • 取值范围:0~UINT64_MAX。

  • 默认值:10000。

  • 单位:行数。

当前默认值表示,当谓词过滤的预估匹配行数少于10000行时,将优先使用谓词前置过滤方法召回匹配的记录,随后对这些记录进行排序,并返回LIMIT指定的行数。

监控向量索引状态

向量索引数据构建任务与列存索引数据快照推进属于不同的后台任务。在持续写入的情况下,向量索引快照位点可能会滞后于列存数据快照。在执行向量检索之前,您需要确认向量索引的可用性。向量索引通过系统视图展示了向量索引的状态,包括向量索引快照位点以及向量列上向量索引的状态。

向量索引快照位点

INFORMATION_SCHEMA.IMCI_INDEX_STATS视图中的VECTOR_ROWS列用于显示列存索引已加载的向量索引快照中的向量数量。若该值为0,则表示当前列存索引上暂无可用的向量索引:可能是表中尚未存在任何向量索引,或是刚创建的向量索引尚未生成有效的向量索引快照。

您还可以把该值与INFORMATION_SCHEMA.IMCI_INDEXES视图中的ROW_ID列进行对比,以粗略评估向量索引数据的构建延迟。即便存在延迟情况,向量索引仍可正常使用;检索时,系统会自动处理尚未写入向量数据。

物理向量索引状态

INFORMATION_SCHEMA.IMCI_VECTOR_INDEX_STATS系统视图展示了向量索引快照内部各个物理向量索引的状态信息,其表结构说明如下:

列名

说明

SCHEMA_NAME

库名。

TABLE_NAME

表名。

COLUMN_NAME

向量列名。

VECTORS

向量索引中实际的向量数目,因为剔除了NULL标记值以及构建时已删除的行,一般比VECTOR_ROWS小。

MEMORY_USAGE

内存用量。

STORAGE_USAGE

持久化文件大小。

INDEX_TYPE

索引类型,目前仅支持HNSW。

INDEX_PARAMETERS

JSON表示的向量索引构建参数。

该视图输出的是每个开启向量索引列对应的向量索引的内存状态及统计信息,与向量索引可用性没有直接关联。

说明
  • 任何未包含在该视图查询结果中的列,都无法进行近似向量检索。

  • 在该视图中,若VECTORS列显示为 0,并不代表向量索引不可用。这通常是因为集群重启后尚未执行增量构建或近似查询,向量索引的持久化数据尚未加载,因而暂时无法获取准确的向量数量。请以系统视图INFORMATION_SCHEMA.IMCI_INDEX_STATS中的VECTOR_ROWS列作为向量快照的准确信息来源。

操作示例

  1. 为确保以下在少量数据的情况下能够正常构建向量索引,需要在PolarDB控制台上将参数imci_vector_index_dump_rows_threshold设置1。

  2. 创建测试表并插入数据:

    CREATE TABLE t1 (
        id int auto_increment PRIMARY KEY,
        v1 vector(4) COMMENT "imci_vector_index=HNSW(metric=COSINE,max_degree=16,ef_construction=300)"
    ) comment "COLUMNAR=1";
    
    INSERT INTO t1 VALUES(1, STRING_TO_VECTOR('[1.1,1.2,1.3,1.4]')), (2, STRING_TO_VECTOR('[2,2.2,2.4,2.6]'));
  3. 检查索引快照状态以及向量索引状态:

    SELECT schema_name,table_name,row_id FROM information_schema.imci_indexes;
    +-------------+------------+--------+
    | schema_name | table_name | row_id |
    +-------------+------------+--------+
    | test        | t1         |      2 |
    +-------------+------------+--------+
    1 row in set (0.00 sec)
    
    SELECT schema_name,table_name,vector_rows FROM information_schema.imci_index_stats;
    +-------------+------------+-------------+
    | schema_name | table_name | vector_rows |
    +-------------+------------+-------------+
    | test        | t1         |           2 |
    +-------------+------------+-------------+
    1 row in set (0.00 sec)
    
    SELECT schema_name,table_name,column_name,vectors FROM information_schema.imci_vector_index_stats;
    +-------------+------------+-------------+---------+
    | schema_name | table_name | column_name | vectors |
    +-------------+------------+-------------+---------+
    | test        | t1         | v1          |       2 |
    +-------------+------------+-------------+---------+
    1 row in set (0.00 sec)
  4. 再执行如下写入数据:

    INSERT INTO t1 VALUES(3, STRING_TO_VECTOR("[8.8,8.88,8.888,8.8888]"));

    可以观察到INFORMATION_SCHEMA.IMCI_VECTOR_INDEX_STATS的相关查询返回结果中VECTORS字段的值为3(增加了1),表示上述INSERT的数据已被后台任务写入向量索引中:

    SELECT schema_name,table_name,column_name,vectors FROM information_schema.imci_vector_index_stats;
    +-------------+------------+-------------+---------+
    | schema_name | table_name | column_name | vectors |
    +-------------+------------+-------------+---------+
    | test        | t1         | v1          |       3 |
    +-------------+------------+-------------+---------+
    1 row in set (0.00 sec)
  5. 接着重启列存索引只读节点后检查索引状态:

    重要

    重启列存索引只读节点会导致当前节点在短暂时间内不可用。

    SELECT schema_name,table_name,row_id,state FROM information_schema.imci_indexes;
    +-------------+------------+--------+-----------+
    | schema_name | table_name | row_id | state     |
    +-------------+------------+--------+-----------+
    | test        | t1         |      3 | COMMITTED |
    +-------------+------------+--------+-----------+
    1 row in set (0.00 sec)
    
    SELECT schema_name,table_name,vector_rows FROM information_schema.imci_index_stats;
    +-------------+------------+-------------+
    | schema_name | table_name | vector_rows |
    +-------------+------------+-------------+
    | test        | t1         |           3 |
    +-------------+------------+-------------+
    1 row in set (0.00 sec)
    
    SELECT schema_name,table_name,column_name,vectors FROM information_schema.imci_vector_index_stats;
    +-------------+------------+-------------+---------+
    | schema_name | table_name | column_name | vectors |
    +-------------+------------+-------------+---------+
    | test        | t1         | v1          |       0 |
    +-------------+------------+-------------+---------+
    1 row in set (0.00 sec)

    可以看到,IMCI_VECTOR_INDEX_STATS系统视图中VECTORS0,同时向量索引快照位点为3。通过执行计划来确认向量索引的可用性,并在执行近似查询后再次检查向量索引状态:

    SET cost_threshold_for_imci = 0;
    
    
    EXPLAIN SELECT * FROM t1 ORDER BY DISTANCE(v1, STRING_TO_VECTOR("[1.2, 2.3, 3.4, 4.5]"), "COSINE") LIMIT 1;
    +----+-----------------------+------+--------+--------+---------------------------------------------------------------------------------------+
    | ID | Operator              | Name | E-Rows | E-Cost | Extra Info                                                                            |
    +----+-----------------------+------+--------+--------+---------------------------------------------------------------------------------------+
    |  1 | Select Statement      |      |        |        | IMCI Execution Plan (max_dop = 4, max_query_mem = 858993459)                          |
    |  2 | +-Compute Scalar      |      |        |        |                                                                                       |
    |  3 |   +-Limit             |      |        |        | Offset=0 Limit=1                                                                      |
    |  4 |     +-Sort            |      |        |        | Sort Key: VECTOR_DISTANCE(t1.v1,"[1.200000,2.300000,3.400000,4.500000]","COSINE") ASC |
    |  5 |       +-Vector Search | t1   |        |        |                                                                                       |
    +----+-----------------------+------+--------+--------+---------------------------------------------------------------------------------------+
    5 rows in set (0.00 sec)
    
    SELECT id, vector_to_string(v1) FROM t1 ORDER BY DISTANCE(v1, STRING_TO_VECTOR("[1.2, 2.3, 3.4, 4.5]"), "COSINE") LIMIT 1;
    +----+---------------------------------------------------+
    | id | vector_to_string(v1)                              |
    +----+---------------------------------------------------+
    |  2 | [2.00000e+00,2.20000e+00,2.40000e+00,2.60000e+00] |
    +----+---------------------------------------------------+
    1 row in set (0.00 sec)
    
    SELECT schema_name,table_name,column_name,vectors FROM information_schema.imci_vector_index_stats;
    +-------------+------------+-------------+---------+
    | schema_name | table_name | column_name | vectors |
    +-------------+------------+-------------+---------+
    | test        | t1         | v1          |       3 |
    +-------------+------------+-------------+---------+
    1 row in set (0.00 sec)

    可以观察到执行近似查询后向量索引被加载到内存,向量个数也恢复为3。

常见问题

为什么向量查询未使用索引?

请按以下步骤排查:

  1. 确认已在会话中执行SET imci_enable_vector_search = ON;SET cost_threshold_for_imci = 0;

  2. 使用EXPLAIN检查执行计划,确认Extra Info列中包含Vector Search算子。

  3. 逐条核对SQL语句是否满足近似最近邻(ANN)检索中列出的所有约束条件。常见错误是未使用LIMITORDER BY的排序方向错误。

  4. 检查DISTANCE(...)表达式中的距离参数metric是否与创建向量索引时使用的距离参数metric完全一致。例如,如果向量索引采用COSINE距离构建,则DISTANCEE(...)也必须指定COSINE

创建向量时报错ERROR 9040 (HY000): Data size exceeds VECTOR max,是什么原因?

定义的向量维度超过了最大限制16383,请减小VECTOR(N)中的N值。

重启列存索引只读节点后,监控显示向量数量VECTORS0,索引是否丢失?

索引没有丢失。这是预期行为。索引数据持久化在磁盘上,重启后需要通过第一次查询来触发加载到内存。请参考监控向量索引状态中的诊断流程。

pq_m参数要求向量维度必须能被整除,如果维度是质数(如1023)怎么办?

在此情况下,无法使用FAISS_HNSW_PQ索引。有以下选择:

  1. 选择其他索引:使用HNSWFAISS_HNSW_FLAT,它们没有此限制,但会占用更多内存。

  2. 调整数据维度:在应用层通过降维或补齐的方式,将向量维度调整为能被pq_m(如8、1632)整除的数值。