向量搜索

本页介绍了如何在 Cloud SQL for MySQL 实例上实现向量搜索。借助 Cloud SQL,您可以将向量嵌入存储在数据库中,创建向量索引,并结合其他存储的数据执行向量搜索

向量嵌入存储

您可以在符合原子性、一致性、隔离性和持久性 (ACID) 属性的表中存储向量嵌入。与表中的其他关系型数据一样,您可以使用现有事务语义来访问表中的向量嵌入。

如需在表行与向量表示法之间建立映射,您需要在表中创建一个列来存储向量嵌入。该列必须使用 Cloud SQL VECTOR 数据类型,并且必须指明嵌入所需的维度数。向量嵌入列只能存储与您在定义该列时指定的维度完全相同的向量嵌入。

一个表只能有一个向量嵌入列。表中的行数没有限制。

为了将向量嵌入列与其他列区分开来,Cloud SQL 会向该列添加特殊的 COMMENTCONSTRAINT。输入验证需要限制条件,而向量嵌入列注解会显示为 COMMENT。您无法修改或删除注释或限制条件。

如果您的 Cloud SQL 实例有足够的可用存储空间和内存,则可以拥有多个具有各自向量嵌入列的表。

向量嵌入列的数据复制方式与其他 MySQL InnoDB 列相同。

如需查看向量嵌入表、列和 DML 语句的限制列表,请参阅限制

向量索引

您必须使用向量索引对向量嵌入执行 ANN 相似度搜索。Cloud SQL 使用可伸缩最近邻 (ScANN) 算法创建向量索引。

向量索引具有以下要求:

  • 每个表只能创建一个向量索引。
  • 如果您的实例中有多个包含向量嵌入的表,则可以为每个表创建向量索引。
  • 如果您要创建向量索引,则无法向编入索引的表的主键添加约束条件。

为了提高搜索质量,请仅在将大部分数据加载到基表中后创建向量索引。如果基表中的嵌入数少于 1000 个,则索引创建将失败。

在决定是否创建向量索引时,如果您有少量行,不妨考虑改为执行 KNN 搜索。选择使用 KNN 还是 ANN 搜索还取决于向量嵌入的维度数。如果嵌入数量较多,则可能需要向量索引。

如需查看矢量索引的限制和限制列表,请参阅限制。如需了解如何创建矢量索引,请参阅创建和管理矢量索引

矢量索引更新

Cloud SQL 会实时更新向量索引。对基表执行数据操纵语言 (DML) 操作的任何事务还会将更改传播到关联的向量索引。向量索引的行为与表中的任何其他二级索引相同。矢量索引完全具有事务一致性,并且符合 ACID 要求。如果回滚事务,则向量索引中也会发生对应的回滚更改。

向量索引的复制

Cloud SQL 会将向量索引复制到所有读取副本,包括级联复制。当您基于具有向量嵌入的主实例创建新的只读副本时,该只读副本会继承主实例的向量嵌入设置。对于现有读取副本,您必须为每个副本启用向量嵌入支持。

在对复制延迟时间的影响方面,向量索引的创建和维护操作方式与常规 MySQL 索引相同。

持久性、关停以及对维护的影响

向量索引的持久化方式与基表相同,并且完全支持 ACID。矢量索引始终与其基表数据保持同步,并且具有相同的可见性、隔离性和崩溃安全性。实例关闭或接受维护时,矢量索引不会受到影响。

索引维护

对基表执行大量 DML 操作后,您基于初始数据(在索引创建时)训练的向量索引可能无法反映新状态。这可能会影响搜索质量。

该索引由两个部分组成:

  • 索引树。此模型是通过对现有数据进行训练而构建的。它在索引的生命周期内保持不变。
  • 索引页面。这些文件包含所有数据行。索引页面绝不会出现同步问题。

运行大量 DML 语句后,索引树的效率可能会降低,因为行会从一个叶子移至另一个叶子。如需刷新索引树,您需要重建索引。

对具有向量索引的表执行不受支持的 DDL 操作

  • 需要复制算法的表更改操作。
  • 需要重新构建表的更改表操作。
  • 删除或更改主键。
  • 将表移至常规表空间。

向量搜索

Cloud SQL 提供向量距离函数,您可以使用这些函数对实例执行近似最近邻 (ANN) 和 K 最近邻 (KNN) 向量相似性搜索。运行查询时,系统会将查询向量与数据集中的向量进行比较。距离函数使用余弦等相似度指标计算向量之间的距离。距离最短的向量最相似,会在搜索结果中返回。

当您执行 ANN 和 KNN 向量搜索时,Cloud SQL 会使用以下函数来衡量向量搜索中的向量之间的距离:

  • 余弦:衡量两个向量之间的余弦角度。值越小,表示向量之间的相似度越高。
  • 点积:计算余弦角度乘以相应矢量大小的乘积。
  • L2 平方距离:通过将每个维度的平方距离相加来衡量两个向量之间的欧几里得距离。

当您需要精确结果或想要添加选择性过滤时,KNN 向量搜索是首选搜索方法。KNN 搜索会计算查询向量与数据集中每个嵌入之间的距离,以查找最近邻。Cloud SQL 中的 KNN 搜索可提供完美的召回率。KNN 搜索不使用矢量索引,因此在处理较小的数据集时,它们是理想之选。

如需执行 KNN 搜索,您可以使用 vector_distance 函数,该函数接受两个矢量作为输入:查询矢量(您要搜索的内容)和数据集中的候选矢量。它会计算这两个向量之间的距离。您在 SELECT 语句中使用了 vector_distance。如需了解详情,请参阅搜索 K 最近邻 (KNN)

如果您发现 KNN 的效果不佳,可以稍后构建向量索引,并继续在应用中使用 approx_distance 进行 ANN 搜索。

如果需要考虑查询效率,ANN 向量搜索是首选搜索类型。它通过计算查询向量与数据集中的部分向量之间的距离来加快相似度搜索速度。为此,Cloud SQL 会将数据整理为集群或分区,然后将搜索重点放在与查询最接近的集群上。ANN 搜索需要使用向量索引。这些索引会优先考虑搜索速度,而不是完全召回。在 Cloud SQL 中,TREE_SQ 索引类型用于 ANN 搜索。

如需执行 ANN 搜索,您可以将 approx_distance 函数与距离测量选项搭配使用。您可以在 ORDER BYSELECT 列表中使用 approx_distance,并且允许使用 LIMIT 子句来限制搜索结果。您还可以添加 WHERE 子句,对搜索结果执行后期过滤。如需了解详情,请参阅搜索近似最近邻 (ANN)

在某些情况下,ANN 搜索会回退到 KNN 搜索。如需了解详情,请参阅检查 ANN 搜索的后备状态

要求

Cloud SQL 要求您先使用 cloudsql_vector 标志在实例上启用向量嵌入,然后才能添加向量嵌入。如需了解详情,请参阅在实例上启用和停用向量嵌入

限制

具有向量嵌入列的表存在以下限制:

  • 每个表只能有一个向量嵌入列。
  • 每个表只能有一个向量索引。
  • 向量嵌入的维度上限为 16,000 个。
  • 向量嵌入列不能是生成的列。
  • 不支持对具有向量嵌入列的表进行表级分区。
  • 向量索引不支持使用 BITBINARYVARBINARYJSONBLOBTEXT 数据类型或空间数据的主键。复合主键也不能包含任何这些类型。
  • 如果存在向量索引,则无法向基表的主键添加约束条件。
  • 如果表中存在向量索引,则您无法执行某些 DDL 操作。如需了解详情,请参阅对包含向量索引的表执行的 DDL 操作不受支持

以下是矢量搜索查询的限制:

  • approx_distance 函数只能在 ORDER BYSELECT 列表中使用。
  • 涉及基表的谓词可在 WHERE 条件中与 ORDER BYSELECT 列表中的 approx_distance 表达式结合使用。系统会在评估 approx_distance 矢量函数后评估 WHERE 条件谓词。

使用向量索引的最佳实践

本部分介绍使用向量索引的最佳实践。每种工作负载各不相同,您可能需要进行相应的调整。

  • 在执行重大 DML 操作后,最好重建索引。
  • 通常,让 Cloud SQL 计算要使用的叶子数量是可以接受的。如果您具有需要指定叶子数量的应用场景,建议每个叶子至少包含 100 个矢量,以便获得最佳召回率。

后续步骤