云原生多模数据库 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 |
| 查询向量时选择的执行方法,有两个值可选择。 |
_l_vector_ef_search_ | 100 | [1,1000] | 可选参数。查询时参数,HNSW算法中,索引查询时动态列表的长度。用来提升数据召回率,数字越大查询性能越慢,范围[1, 1000]。 |
_l_vector_topk_ | 10 | [1,+inf] | 查询向量的topK值,一般建议与limit值保持一致。 |