本页面介绍了可用于查询向量嵌入的不同方式。如需简要了解 ANN 和 KNN 相似度搜索,请参阅向量搜索。
搜索近似最近邻 (ANN)
如需执行 ANN 搜索,请在 SELECT 和 ORDER BY 子句中使用 approx_distance 函数。您必须在 ANN 搜索中使用 LIMIT 子句。您还可以通过将 approx_distance 放入 SELECT 列表中来获取距离值。
请使用以下语法进行 ANN 查询:
# Ordering by distance
SELECT title
FROM books
ORDER BY approx_distance(embedding, string_to_vector('[1,2,3]'), 'distance_measure=l2_squared')
LIMIT 4;
# Selecting the distance value
SELECT
approx_distance(
embedding_name,
string_to_vector('[1,2,3]'),
'distance_measure=cosine,num_leaves_to_search=3')
dist
FROM table
ORDER BY dist
LIMIT limit_value;
approx_distance 函数使用以下选项:
embedding:使用基表中的向量嵌入列名称。string_to_vector或vector_to_string:将向量转换为字符串,将字符串转换为向量,以使向量易于人类可读。distance_measure:指定要用于向量相似度搜索的距离测量值。此值必须与创建索引时在distance_measure参数中设置的值一致。此参数必不可少。此参数的可能值包括:COSINEL2_SQUAREDDOT_PRODUCT
num_leaves_to_search:可选。指定要为 ANN 向量相似度搜索探测的叶数量。如果您未指定叶数量,Cloud SQL 会使用根据表大小、向量索引中的叶数量以及其他因素生成的值。您可以在information_schema.innodb_vector_indexes中查看此值。我们建议您对num_leaves_to_search进行微调,以便针对您的特定工作负载在搜索质量和性能之间取得最佳平衡。如果该值增加,会影响性能,但会提高召回率。
以下示例展示了如何通过 approx_distance 使用 l2_squared 距离测量值查找前 K 个最近的行,并按距离对结果进行排序。
# Ordering by distance
SELECT title
FROM books
ORDER BY approx_distance(embedding, string_to_vector('[1,2,3]'),
'distance_measure=l2_squared')
LIMIT 4;
# Selecting the distance value
SELECT
approx_distance
(embedding, string_to_vector('[1,2,3]'),
'distance_measure=l2_squared') dist
FROM table
ORDER BY dist
LIMIT 4;
过滤来自 approx_distance 查询的结果
您可以将 approx_distance 函数与使用非向量谓词过滤查询结果的 WHERE 条件结合使用,以执行后过滤。系统会在应用过滤条件之前评估 approx_distance 函数,这意味着返回的结果数不确定。
例如,对于以下查询:
SELECT id FROM products WHERE price < 100
ORDER BY approx_distance(embedding, @query_vector,'distance_measure=cosine')
LIMIT 11;
approx_distance 函数会返回查询向量的 11 个最近邻,无论价格如何。在后过滤中,系统会选择价格低于 100 的商品。所有最近邻的价格都可能小于 100,因此查询结果为 11 个。或者,如果没有任何最近邻价格低于 100,则系统会返回 0 行。
如果您预计 WHERE 条件中的过滤条件非常严格,则精确搜索 (KNN) 是一种可确保返回足够数量的行的选择。
另一种方法是使用迭代过滤来扫描更多 ANN 搜索索引。
使用迭代过滤来增加 ANN 搜索结果
当 ANN 搜索查询中 WHERE 子句的选择性过滤条件生成的结果数量少于 LIMIT 子句中指定的结果数量时,您可以使用迭代过滤。
例如,在以下查询中,启用迭代过滤后,查询会扫描更多向量索引,但会排除第一组过滤结果。
EXPLAIN FORMAT=TREE
SELECT * FROM t1 WHERE next_id BETWEEN 15 AND 100
ORDER BY approx_distance(embedding, string_to_vector('[1,2,3]'), 'distance_measure=l2_squared')
LIMIT 10;
EXPLAIN
-> Limit: 10 row(s) (rows=10)
-> Vector index loop with iterative filtering
-> Vector index scan on t1
-> Filter: (t1.next_id between 15 and 100)
-> Single-row index lookup on t1 using PRIMARY (id=t1.id)
您可以从搜索向量索引中以迭代方式提取更多近邻项,直到达到配置的最大值 (cloudsql_vector_iterative_filtering_max_neighbors)。任何过滤条件匹配项都会计入 LIMIT,并从额外的向量索引扫描中移除。
启用迭代过滤
默认情况下,系统会针对所有会话和 Cloud SQL 实例停用迭代过滤。
如需为现有会话启用迭代过滤,请使用以下 SQL 语句。
SET SESSION cloudsql_vector_iterative_filtering=on;
您还可以通过在实例上设置标志,为连接到该实例的所有客户端会话全局启用迭代过滤。如需为实例设置标志,请参阅设置数据库标志。
如需详细了解如何在会话或全局级别设置系统变量,请参阅 MySQL 文档中的使用系统变量。
调整迭代过滤
如需控制在启用迭代过滤的情况下,ANN 搜索查询返回的最近邻数量,您可以使用 cloudsql_vector_iterative_filtering_max_neighbors 会话或全局系统变量。您可以使用此配置来增加请求的最近邻数量。不过,为避免在内存中存储过多的结果,此变量的最大值为 1000。
如需为会话设置此变量,请使用以下 SQL 语句:
SET cloudsql_vector_iterative_filtering_max_neighbors=600;
默认值为 500,最小值为 10。
限制
使用迭代过滤存在以下限制:
不保证:使用迭代过滤时,Cloud SQL 会尝试查找
LIMIT子句中指定的结果数量,但不保证一定能找到该数量的结果。如果尚未满足LIMIT就已达到近邻数量上限 (cloudsql_vector_iterative_filtering_max_neighbors),或者表中没有足够多的行与过滤条件匹配,就会发生这种情况。复杂查询:只有在过滤条件谓词下推到基本表的访问路径时,迭代过滤才有效。不支持对临时表之上的过滤条件使用此功能;例如,使用
HAVING子句的表。在子查询中,只有子查询本身中对基表的过滤条件才会被纳入迭代过滤的考虑范围。
检查 ANN 搜索的回退状态
在某些情况下,ANN 搜索会回退到 KNN 搜索。这些情况包括:
- 基表上没有向量索引。
- 基表上有向量索引,但它使用的是与
approx_distance搜索选项中的distance_measure参数不同的距离测量值。 - 向量索引损坏或对当前事务不可见。
- 指定的
LIMIT大于 10,000。 - 未指定
LIMIT。 - 当前查询涉及对同一基表的多次
approx_distance调用。 - 优化器计算出使用 KNN 更高效。
所有这些情况都会向客户端推送警告,表明执行了精确搜索以及原因。
在 MySQL 客户端中使用以下命令查看回退状态:
SHOW global status LIKE '%cloudsql_vector_knn_fallback%';
如果您想使用 ANN,但它回退到 KNN,则查询运行速度可能更慢。您应找出其回退的原因,并评估是否要进行更改以改用 ANN。
示例:创建向量索引并运行 ANN 查询
以下示例演示提供了在 Cloud SQL 中创建向量索引并运行 ANN 查询的步骤。
- 生成向量嵌入。您可以手动创建向量嵌入,也可以使用自己选择的文本嵌入 API。如需查看使用 Vertex AI 的示例,请参阅根据行数据生成向量嵌入。
在 Cloud SQL 中创建一个表,其中包含一个具有三个维度的向量嵌入列。
CREATE TABLE books( id INTEGER PRIMARY KEY AUTO_INCREMENT, title VARCHAR(60), embedding VECTOR(3) USING VARBINARY);在该列中插入一个向量嵌入。
INSERT INTO books VALUES ((1, 'book title', string_to_vector('[1,2,3]')));提交更改。
commit;使用
L2_squared函数创建向量索引以衡量距离。CREATE VECTOR INDEX vectorIndex ON dbname.books(embeddings) USING SCANN QUANTIZER = SQ8 DISTANCE_MEASURE = l2_squared;使用以下语法执行 ANN 搜索,
LIMIT为 4 个搜索结果:SELECT title FROM books ORDER BY approx_distance(embedding, string_to_vector('[1,2,3]'), 'distance_measure=l2_squared') LIMIT 4; SELECT approx_distance(embedding, string_to_vector('[1,2,3]'), 'distance_measure=cosine') dist FROM books ORDER BY dist LIMIT 4;
搜索 K 最近邻 (KNN)
如需执行 K 最近邻搜索,请在 SELECT 语句中使用 vector_distance 函数、距离测量选项和向量转换函数(string_to_vector 或 vector_to_string)。请使用下面的语法:
SELECT vector_distance(string_to_vector('[1,2,3]'),
string_to_vector('[1,2,3]'),
'Distance_Measure=dot_product');
将值 [1,2,3] 替换为数据的嵌入值。
以下示例展示了如何将此查询与 cosine_distance 函数和 string_to_vector 向量转换函数结合使用。
SELECT id,cosine_distance(embedding, string_to_vector('[1,2,3]')) dist
FROM books
ORDER BY distance
LIMIT 10;
在 KNN 查询中获取余弦距离
使用 Cloud SQL cosine_distance 函数通过余弦计算距离。
SELECT cosine_distance(embedding, string_to_vector('[3,1,2]')) AS distance FROM books WHERE id = 10;
在 KNN 查询中获取点积距离
使用 Cloud SQL dot_product 函数通过点积计算距离。
SELECT dot_product(embedding, string_to_vector('[3,1,2]')) AS distance FROM books WHERE id = 10;
在 KNN 查询中获取 L2 平方距离
使用 Cloud SQL l2_squared_distance 函数通过 L2 平方计算距离。
SELECT
l2_squared_distance(embedding, string_to_vector('[3,1,2]'))
AS distance
FROM books
WHERE id = 10;
后续步骤
- 阅读 Cloud SQL 中的向量搜索概览。
- 了解如何在实例上启用和停用向量嵌入。
- 了解如何生成向量嵌入。
- 了解如何创建向量索引。
- 了解如何对向量嵌入执行搜索。