使用向量嵌入搜索和过滤

本页面介绍了可用于查询向量嵌入的不同方式。如需简要了解 ANN 和 KNN 相似度搜索,请参阅向量搜索

搜索近似最近邻 (ANN)

如需执行 ANN 搜索,请在 SELECTORDER 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_vectorvector_to_string:将向量转换为字符串,将字符串转换为向量,以使向量易于人类可读。
  • distance_measure:指定要用于向量相似度搜索的距离测量值。此值必须与创建索引时在 distance_measure 参数中设置的值一致。此参数必不可少。此参数的可能值包括:
    • COSINE
    • L2_SQUARED
    • DOT_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(embedding, @query_vector,'distance_measure=cosine')
LIMIT 11;

approx_distance 函数会返回查询向量的 11 个最近邻,无论价格如何。在后过滤中,系统会选择价格低于 100 的商品。所有最近邻的价格都可能小于 100,因此查询结果为 11 个。或者,如果没有任何最近邻价格低于 100,则系统会返回 0 行。

如果您预计 WHERE 条件中的过滤条件非常严格,则精确搜索 (KNN) 可能是更好的选择,可确保返回足够数量的行。

查看 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 查询的步骤。

  1. 生成向量嵌入。您可以手动创建向量嵌入,也可以使用自己选择的文本嵌入 API。如需查看使用 Vertex AI 的示例,请参阅根据行数据生成向量嵌入
  2. 在 Cloud SQL 中创建一个表,其中包含一个具有三个维度的向量嵌入列。

    CREATE TABLE books(
    id INTEGER PRIMARY KEY AUTO_INCREMENT, title VARCHAR(60), embedding VECTOR(3) USING VARBINARY);
    
  3. 在该列中插入一个向量嵌入。

    INSERT INTO books VALUES ((1, 'book title', string_to_vector('[1,2,3]')));
    
  4. 提交更改。

    commit;
    
  5. 使用 L2_squared 函数创建向量索引以测量距离。

    CREATE
      VECTOR INDEX vectorIndex
    ON dbname.books(embeddings)
    USING SCANN QUANTIZER = SQ8 DISTANCE_MEASURE = l2_squared;
    
  6. 使用以下语法,以 LIMIT 为 4 的搜索结果执行 ANN 搜索:

    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_vectorvector_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;

后续步骤