更新时间:2026-08-05 GMT+08:00
分享

向量存储检索

操作场景

在企业级应用中,随着业务数据量的快速增长,高效向量检索的需求日益迫切。然而,传统的“关系数据库 + 独立向量数据库”分离式架构存在数据同步复杂、维护成本高、系统一致性差等问题。为满足企业级场景对向量检索能力的需求,数据库支持向量索引已成为重要的发展方向。

向量(Vector)是将文本、图像等非结构化数据通过嵌入模型映射到高维数值空间后得到的浮点数序列。在向量空间中,语义相近的数据点彼此距离更近,因此可通过计算向量间的距离来衡量数据的语义相似性。该技术广泛应用于语义搜索、推荐系统等场景。然而随着数据规模增长,对海量高维向量进行精确最近邻搜索面临维度灾难,计算复杂度难以满足实时性要求,向量索引由此应运而生。RDS采用HNSW(Hierarchical Navigable Small World)算法构建向量索引,通过多层级导航小世界图实现对数级时间复杂度的近似最近邻搜索,并支持欧氏距离(Euclidean Distance)和余弦距离(Cosine Distance)两种距离度量方式。

RDS借助支持向量索引,为企业级应用提供高效、一致且易于维护的向量检索方案。相比传统的分离式架构,RDS在统一的数据存储与事务体系下,实现结构化数据与向量数据的一体化管理及联合查询,从而降低多系统间的数据同步与维护成本,显著提升系统一致性、查询效率以及整体运维稳定性。

版本约束

RDS实例内核版本大于等于8.0.43.260600,支持原生向量。

原理介绍

向量(Vector)是将文本、图片等非结构化数据通过嵌入模型(Embedding Model)转换得到的一组高维数值。语义相近的数据通常会映射到向量空间中相近的位置,因此可以通过计算向量之间的距离来衡量数据的相似度。RDS当前支持欧氏距离(L2)和余弦距离(Cosine)两种距离度量方式。

传统B+Tree索引适用于精确匹配和范围查询,但无法高效支持高维向量的相似度检索。为此,RDS引入HNSW(Hierarchical Navigable Small World)向量索引,通过构建多层近邻图来组织向量数据。查询时,从高层入口节点开始逐层搜索,快速定位与目标向量最接近的候选节点,最终返回Top-K相似结果。

在存储层面,每个向量索引对应一张隐藏的辅助表,用于持久化保存HNSW图节点及邻接关系。这样可以直接复用InnoDB的事务、恢复和锁机制,无需额外设计专用存储引擎,在保证数据一致性的同时提供高效的向量检索能力。

约束与限制

表1 约束与限制

类别

约束和限制

存储与引擎

仅支持InnoDB存储引擎,事务上只支持READ-COMMITTED隔离级别,与辅助表持久化机制关联。

向量属性

  • 向量维度最大为16383,最小为1。
  • 向量精度为IEEE 754单精度浮点(32 位)。
  • 向量列可以为NULL,但不会写入索引。向量索引要求向量列有确定的值,NULL无法参与距离计算。
  • 向量列中存在NaN或Inf值时,写入失败,无法计算距离。
  • 0向量和任何向量的余弦距离规定为1。

向量索引

  • 使用HNSW算法,这是一种业界验证的高效近似最近邻(ANN)算法,支持欧式距离与余弦距离,召回率高。
  • 向量索引不可设置为INVISIBLE,始终参与优化器决策。
  • 单表可以创建多个向量列,但只能创建一个单列向量索引,不支持联合索引。
  • 向量索引仅对带LIMIT的查询生效。
  • 向量索引只支持ASC排序。
  • HNSW算法具有随机性(层级分配、启发式选邻),因此无法保证主备向量索引图结构一致。

表类型与DDL操作

  • 带向量索引的表不支持分区表和临时表。
  • 向量索引创建和删除需重建辅助表,用于存储HNSW图的节点和邻居关系。每个带向量索引的基表都会创建一个对应的辅助表,不支持在线DDL操作。

功能限制

  • 在源数据库中的存储过程、函数中使用vector类型,会导致迁移到不支持向量的目标数据库失败。
  • 包含向量索引的表不支持库表回收站功能。
  • DRS暂未支持向量功能,如因开启向量功能导致全量迁移失败,请提交工单处理。

向量参数说明

表2 向量参数

参数名

参数类型

取值范围

默认值

说明

transaction_isolation

String

READ-UNCOMMITTED/READ-COMMITTED/REPEATABLE-READ/SERIALIZABLE

READ-COMMITTED

事务隔离级别。向量操作仅支持READ-COMMITTED隔离级别,其余隔离级别不支持。

rds_vidx_disabled

GLOBAL_BOOL

ON/OFF

ON

向量功能开关。

  • ON:禁用向量功能。
  • OFF:开启向量功能。如需开启,请提交工单

rds_vidx_default_distance

SESSION_ENUM

EUCLIDEAN/COSINE

EUCLIDEAN

默认距离类型。

  • EUCLIDEAN:欧式距离。
  • COSINE:余弦距离。

rds_vidx_hnsw_default_m

SESSION_UINT

3~200

6

HNSW参数M,图节点的邻居数量。

rds_vidx_hnsw_ef_search

SESSION_UINT

1~10000

20

搜索时的队列大小。

rds_vidx_hnsw_cache_size

GLOBAL_ULONGLONG

1MB~1GB

16MB

HNSW缓存大小限制。

向量函数

  • VEC_FROMTEXT(str)
    • 描述

      将JSON数组格式的文本字符串转换为二进制VECTOR值。例如将 '[1.0, 2.0, 3.0]' 转为内部浮点数序列的二进制表示。最大支持16383维。

    • 别名:

      TO_VECTOR、STRING_TO_VECTOR,功能与VEC_FROMTEXT完全相同。

    • 参数说明:

      str:VARCHAR类型,JSON数组格式的字符串,如 '[1.0, 2.0, 3.0]'。不支持JSON类型或Geometry类型参数。

  • VEC_TOTEXT(vector)
    • 描述:

      将二进制VECTOR值转换为JSON数组格式的文本字符串,返回如 '[1.0, 2.0, 3.0]' 的可读文本,字符集为utf8mb4_0900_bin。

    • 别名:

      FROM_VECTOR、VECTOR_TO_STRING,功能与VEC_TOTEXT完全相同。

    • 参数说明:

      vector:VECTOR类型(二进制字符串),即内部存储的向量值。

  • VEC_DISTANCE(v1, v2)
    • 描述:

      计算两个向量之间的距离。自动根据列上定义的VECTOR INDEX的距离度量类型来选择计算方式:

      若索引为EUCLIDEAN则计算L2距离,若为COSINE则计算余弦距离。

      如果找不到适用的向量索引,则报错。当任一输入为NULL、维度不匹配、或计算结果非有限值时返回NULL。

    • 参数说明:
      • v1:VECTOR类型,第一个向量,必须是向量索引列(用于索引查找优化)。
      • v2:VECTOR类型,第二个向量,常量,两个向量的维度必须一致。
  • VEC_DISTANCE_EUCLIDEAN(v1, v2)
    • 描述:

      计算两个向量之间的欧几里得距离(L2 距离),公式为sqrt(sum((v1[i] - v2[i])²))。当任一输入为NULL、维度不匹配、或计算结果非有限值时返回NULL。

    • 参数说明:

      v1、v2:VECTOR 类型,两个向量都是任意向量表达式(常量、有索引向量列、无索引向量列),且维度必须一致。

  • VEC_DISTANCE_COSINE(v1, v2)
    • 描述:

      计算两个向量之间的余弦距离,公式为 1 - dot(v1, v2) / (|v1| × |v2|)。当任一输入为NULL、维度不匹配、或计算结果非有限值时返回NULL。

    • 参数说明:

      v1、v2:VECTOR 类型,两个向量都是任意向量表达式(常量、有索引向量列、无索引向量列),且维度必须一致。

  • VECTOR_DIM(vector)
    • 描述:

      返回向量的维度数(即浮点元素的个数)。计算方式为二进制长度除以 sizeof(float)(4 字节)。

    • 参数说明:

      vector:VECTOR类型(二进制字符串),即内部存储的向量值。返回BIGINT类型。

创建向量列

在CREATE TABLE或ALTER TABLE语句中使用VECTOR(N)类型定义N维向量列。

其中N表示维度,N∈[1,16383]。

  • 创建包含向量列的新表。
    CREATE TABLE items (
        id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
        name VARCHAR(255),
        embedding VECTOR(128)
    );
  • 将向量列添加到现有表中。
    ALTER TABLE products ADD COLUMN description_vec VECTOR(64);

使用向量索引

  • 创建HNSW向量索引。
    CREATE VECTOR INDEX idx ON t(v)

    示例:

    在表items的向量列embedding上创建名为 vidx 的向量索引,使用默认参数。

    CREATE VECTOR INDEX vidx ON items(embedding);
  • 指定索引参数,指定邻居数M和距离类型。
    CREATE VECTOR INDEX idx ON t(v) M=N DISTANCE=metric

    示例:

    在表items的向量列embedding上创建索引vidx,指定每个节点最大连接数M为16,距离类型为余弦距离。

    CREATE VECTOR INDEX vidx ON items(embedding) M=16 DISTANCE=COSINE;
  • 建表时创建向量索引。
    CREATE TABLE t(..., VECTOR INDEX(v))

    示例:

    创建表items,包含自增主键id、128维向量列embedding,并同时创建名为vidx的向量索引,指定M=16,距离类型为欧式距离。

    CREATE TABLE items (
        id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
        embedding VECTOR(128),
        VECTOR INDEX vidx(embedding) M=16 DISTANCE=EUCLIDEAN
    );
  • 删除向量索引。
    ALTER TABLE t DROP VECTOR INDEX idx

    示例:

    删除表items上的向量索引vidx。

    ALTER TABLE items DROP INDEX vidx;

向量查询

  • 向量排序查询,返回Top-N相似向量。
    SELECT * FROM t ORDER BY VEC_DISTANCE(v, query_vec) LIMIT N

    示例:

    查询表items中与向量 [1.0, 0.5, 0.8, ...] 最相似的前10条记录,embedding为向量列,VEC_FROMTEXT('[1.0,0.5,0.8,0.2,0.3]') 将文本转为查询向量。

    SELECT * FROM items
    ORDER BY VEC_DISTANCE(embedding, VEC_FROMTEXT('[1.0,0.5,0.8,0.2,0.3]'))
    LIMIT 10;
  • 混合条件查询,先过滤后排序,结合标量条件。
    SELECT * FROM t WHERE category='A' ORDER BY VEC_DISTANCE(v, query_vec) LIMIT N

    示例:

    查询表items中category为 'electronics' 且与查询向量最相似的前5条记录,先按category过滤再按向量距离排序。

    SELECT * FROM items
    WHERE category = 'electronics'
    ORDER BY VEC_DISTANCE(embedding, VEC_FROMTEXT('[1.0,0.5,0.8,0.2,0.3]'))
    LIMIT 5;
  • 显示计算的距离值。
    SELECT id, VEC_DISTANCE(v, query_vec) AS dist FROM t ORDER BY dist LIMIT N

    示例

    查询表items中与查询向量最相似的前10条记录,并显示每条记录的id和距离值dist。

    SELECT id, VEC_DISTANCE(embedding, VEC_FROMTEXT('[1.0,0.5,0.8,0.2,0.3]')) AS dist
    FROM items
    ORDER BY dist
    LIMIT 10;
  • 强制使用向量索引。
    SELECT * FROM t FORCE INDEX(vidx) ORDER BY VEC_DISTANCE(v, query_vec)

    示例:

    强制使用向量索引vidx查询表items中与查询向量最相似的前10条记录。

    SELECT * FROM items
    FORCE INDEX(vidx)
    ORDER BY VEC_DISTANCE(embedding, VEC_FROMTEXT('[1.0,0.5,0.8,0.2,0.3]'))
    LIMIT 10;

使用示例

  1. 提交工单开启向量功能。
  2. 设置隔离级别。
    SET transaction_isolation = 'READ-COMMITTED';
  3. 创建表和向量索引。
    CREATE TABLE product_embeddings (
    id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
    product_name VARCHAR(255),
    embedding VECTOR(5) NOT NULL,
    -- 创建向量索引,并指定M值和距离计算方式
    VECTOR INDEX idx_embedding(embedding) M=16 DISTANCE=COSINE
    );
  4. 插入数据。
    INSERT INTO product_embeddings (product_name, embedding) VALUES
    ('product_A', VEC_FROMTEXT('[0.1, 0.2, 0.3, 0.4, 0.5]')),
    ('product_B', VEC_FROMTEXT('[0.6, 0.7, 0.8, 0.9, 1.0]')),
    ('product_C', VEC_FROMTEXT('[0.11, 0.22, 0.33, 0.44, 0.55]'));
  5. 进行向量相似度查询。
    -- 查找与给定向量 '[0.1, 0.2, 0.3, 0.4, 0.51]' 最相似的2个商品
    SELECT id, product_name, VEC_DISTANCE(embedding, VEC_FROMTEXT('[0.1, 0.2, 0.3, 0.4, 0.51]')) AS similarity_score
    FROM product_embeddings ORDER BY
    similarity_score ASC    -- COSINE距离越小越相似
    LIMIT 2;

相关文档