向量检索

更新时间:
复制为 MD 格式

云原生多模数据库 Lindorm支持通过搜索索引使用向量检索功能,本文介绍如何通过搜索索引及SQL方式完成向量检索。

前提条件

数据准备

通过MySQL命令行连接并使用宽表引擎,准备SQL表并写入样例数据。

连接宽表引擎创建SQL

以下示例中,vector_column用于写入向量数据,向量列的类型定义为VARCHAR

CREATE TABLE test_vector_table (
  id VARCHAR,
  name VARCHAR,
  age INT,
  vector_column VARCHAR,
  PRIMARY KEY (id)
);

写入样例数据

向量列vector_column写入的格式应为'[...]',由方括号包围的浮点数数组。

UPSERT INTO test_vector_table (id, name, age, vector_column) VALUES ('1', 'user_1', 18, '[0.067985594, 0.94134957, 0.9174301, 0.34755236, 0.3318444, 0.30996937, 0.12764448, 0.9909833]');
UPSERT INTO test_vector_table (id, name, age, vector_column) VALUES ('2', 'user_2', 30, '[0.48320667, 0.12729345, 0.86240918, 0.57118409, 0.09480932, 0.69527483, 0.31873674, 0.23437815]');

创建搜索索引

通过MySQL命令行连接并使用宽表引擎,创建包含向量列的搜索索引。

向量列类型需指定为 type=vector,维度参数 dims 必须与写入数据的维度保持一致(示例中为 8)。其他可选参数请参考向量索引参数说明

示例一:使用 HNSW 算法

CREATE INDEX vector_idx USING SEARCH ON test_vector_table (
	id,
	name(type=text, analyzer=ik),
	age,
	vector_column(type=vector, dims=8, algorithm=HNSW, distance_method=L2, ef_construct=100, maximum_degree=16)
) WITH (
  INDEX_SETTINGS='{
    "knn": true,
    "knn.vector_number_of_regions": "10"
  }',
  SOURCE_SETTINGS='{
    "excludes": ["vector_column"]
  }'
);

示例二:使用 IVFPQ 算法

CREATE INDEX vector_idx USING SEARCH ON test_vector_table (
	id,
	name(type=text, analyzer=ik),
	age,
	vector_column(type=vector, dims=8, algorithm=IVFPQ, distance_method=L2, nlist=1000)
) WITH (
  INDEX_SETTINGS='{
    "knn": true,
    "knn.offline.construction": true,
    "knn.vector_number_of_regions": "10"
  }',
  SOURCE_SETTINGS='{
    "excludes": ["vector_column"]
  }'
);
说明

使用IVFPQ算法时,knn.offline.construction 必须设置为 true。索引构建需要写入一定量的数据后才能发起。当前发起离线索引构建的方式可参考索引构建

其中,参数knn.vector_number_of_regions为非必选,表示向量索引的分片数,默认为向量节点个数。

向量索引参数说明

通用参数

名称

默认值

取值范围

描述

dims

128

[1,32768]

向量列维度。

algorithm

HNSW

HNSW,FLAT,IVFPQ

向量索引使用的算法。

distance_method

L2

L2,IP,COSINE

计算距离公式。

HNSW 算法参数

名称

默认值

取值范围

描述

maximum_degree

16

[1,100]

出边数量,值越大越精确,内存占用高。

ef_construct

100

[1,1000]

动态列表长度。

IVFPQ算法参数

名称

默认值

取值范围

描述

m

16

[2,32768]

量化中子空间的数量,必须和dim保持一致,否则创建会报错。

nlist

10000

[2,1000000]

聚类中心的数量。

centroidsHnswEnabled

true

true,false

是否在聚类中心搜索时使用HNSW算法。

centroidsHnswMaximumDegree

16

[1,100]

若在聚类中心搜索时使用HNSW算法,设定HNSW算法的每一层图的最大出边数量。

centroidsHnswEfConstruct

100

[1,1000]

若在聚类中心搜索时使用HNSW算法,设定HNSW算法在索引构建时动态列表的长度。

centroidsHnswEfSearch

100

[1,1000]

若在聚类中心搜索时使用HNSW算法,设定HNSW算法在查询时动态列表的长度。

查询数据

查询方式分为纯向量检索和融合检索两种。向量距离通过VECTOR_DISTANCE函数计算,实际使用的距离算法在创建向量索引时指定。

纯向量检索

SQL查询中不带其他标量条件时为纯向量检索,以下示例计算每条记录的vector_column与给定查询向量的距离,并返回距离最近的10条记录。

SELECT name,age 
FROM test_vector_table
ORDER by 
  vector_distance(vector_column, '[0.067985594, 0.94134957, 0.9174301, 0.34755236, 0.3318444, 0.30996937, 0.12764448, 0.9909833]')
LIMIT 10;

融合检索

SQL查询中带其他标量及全文条件时为融合检索,目前仅支持标量过滤的融合方式,可通过HINT语法调整融合检索的各项参数,目前支持的参数及含义参考下表内容。

以下SQL示例中,指定融合检索的方式为FILTER_FIRST,会先进行结构化或全文条件的过滤,再对过滤后的数据执行向量匹配,返回结果集中距离最近的 10 条数据。

SELECT /*+ _l_vector_search_(FILTER_FIRST) */ name, age
FROM test_vector_table
WHERE MATCH(name) AGAINST('user')
ORDER by
  vector_distance(vector_column, '[0.067985594, 0.94134957, 0.9174301, 0.34755236, 0.3318444, 0.30996937, 0.12764448, 0.9909833]')
LIMIT 10;

支持指定的参数:

名称

默认值

取值范围

描述

_l_vector_search_

VECTOR_FIRST

  • VECTOR_FIRST(默认值):等同post_filter,先向量查询,再结构化过滤。性能快,召回率可能不高。

  • FILTER_FIRST:等同pre_filter,先结构化过滤所有数据,再向量匹配topK。召回率高,性能慢。

查询向量时选择的执行方法,有两个值可选择。

_l_vector_ef_search_

100

[1,1000]

可选参数。查询时参数,HNSW算法中,索引查询时动态列表的长度。用来提升数据召回率,数字越大查询性能越慢,范围[1, 1000]。

_l_vector_topk_

10

[1,+inf]

查询向量的topK值,一般建议与limit值保持一致。