Spanner Omni 中的向量搜索是一项高性能的内置功能,可对高维向量数据进行语义搜索和相似度匹配。通过直接在事务型数据库中存储和索引向量嵌入,Spanner Omni 消除了单独的向量数据库以及复杂的提取、转换、加载 (ETL) 流水线。
本文档中的主题适用于 Spanner Omni,就像它们适用于 Spanner 一样。
向量搜索概览
借助向量搜索,您可以通过将数据表示为数值向量(嵌入)来查找语义相似的项。Spanner Omni 支持两种主要搜索方法:
K 最近邻 (KNN):通过计算查询与数据集中每个向量之间的 距离来执行精确搜索。它可以提供最高的召回率,但对于大型数据集来说,计算成本可能很高。
近似最近邻 (ANN):使用向量索引在大型数据集中快速查找匹配项 。它会牺牲少量准确率(召回率),以换取速度和可伸缩性提升。
与其他功能结合使用时,向量搜索尤其强大:
| 组合 | 有利 |
|---|---|
| 使用 SQL 过滤条件的向量搜索 | 高效地将向量搜索与过滤条件相结合(例如“查找类别为‘鞋子’且价格低于 100 的相似图片”)。 |
| 向量搜索 + 全文搜索 | 使用倒数排名融合 (RRF) 将语义相似度与关键字精确度相结合,以提高搜索相关性。 |
| 向量 + 图 | 使用向量搜索在属性图中查找相关入口点(节点),然后遍历复杂关系。 |
如需了解详情,请参阅 Spanner 向量搜索概览 在 Spanner 文档中。
执行 K 最近邻搜索
Spanner Omni 支持使用内置距离函数进行 K 最近邻 (KNN) 搜索。您可以提供向量嵌入作为输入参数,以查找 N 维空间中最接近的向量。
以下距离函数可用:
COSINE_DISTANCE():计算两个向量之间夹角的余弦值EUCLIDEAN_DISTANCE():计算两个向量之间的最短直线距离DOT_PRODUCT():计算夹角的余弦值与向量大小的乘积(非常适合归一化数据)
如需了解详情,请参阅 Spanner 文档中的通过查找 K 最近邻来执行向量相似度搜索 。
选择最佳向量距离函数
选择合适的距离函数取决于您的数据以及用于生成嵌入的模型。
| 函数 | 说明 | 与相似度增加的关系 |
|---|---|---|
| 点积 | 计算夹角的余弦值与相应向量大小的乘积。 | 增加 |
| 余弦距离 | 计算两个向量之间夹角的余弦值(1 - 余弦相似度)。 | 减少 |
| 欧几里得距离 | 衡量两个向量之间的直线距离。 | 减少 |
如果您的嵌入已归一化(大小 = 1.0),则 DOT_PRODUCT() 通常是一个高效的选择。对于非归一化数据,请尝试使用 COSINE_DISTANCE() 或 EUCLIDEAN_DISTANCE(),以确定哪种函数最适合您的使用场景。
如需了解详情,请参阅 在向量距离函数之间进行选择 在 Spanner 文档中。
近似最近邻 (ANN)
ANN 搜索专为非常大的数据集而设计,在这些数据集中,精确的 KNN 搜索会变得太慢或成本太高。它使用向量索引来提供快速结果,但召回率会略有降低。
Spanner Omni 中的近似最近邻 (ANN) 搜索支持最多包含 100 万个向量的数据集,向量长度最多为 128 维。如果您的向量具有更多维度,则支持的向量数量会按比例减少。
使用向量索引执行 ANN 搜索
如需执行 ANN 搜索,您可以使用近似距离函数,例如 APPROX_COSINE_DISTANCE()、APPROX_EUCLIDEAN_DISTANCE() 或 APPROX_DOT_PRODUCT()。这些函数需要:
嵌入列上现有的向量索引。
使用近似距离函数的
ORDER BY子句。用于指定结果数量的
LIMIT子句。
如需了解详情,请参阅 Spanner 文档中的查找近似最近邻 (ANN) 和查询向量嵌入 。
创建和管理向量索引
创建向量索引时,您必须指定嵌入列的 vector_length,并且可以使用 STORING 子句来包含其他列,以便更快地进行过滤。
以下示例展示了如何创建向量索引:
CREATE VECTOR INDEX INDEX_NAME
ON TABLE_NAME(EMBEDDING_COLUMN)
OPTIONS (distance_type = 'DISTANCE_TYPE', tree_depth = 2, num_leaves = 1000);
如需了解详情,请参阅 Spanner 文档中的创建和管理向量索引 。
向量索引编制最佳实践
如需保持较高的搜索性能和召回率,请执行以下操作:
调整索引选项:根据您的数据大小和性能要求调整
num_leaves和num_leaves_to_search。定期重建:如果向量的分布随时间推移而发生显著变化,请重建索引。
有效使用过滤条件:将经常过滤的列存储在 索引中,以提高搜索效率。
如需了解详情,请参阅 Spanner 文档中的向量索引编制最佳实践 。