本页面介绍了如何使用 ANN 距离函数查找近似最近邻 (ANN) 并查询向量嵌入。
如果数据集较小,您可以使用 K 最近邻 (KNN) 来查找精确的 k 最近邻向量。不过,随着数据集的增大,KNN 搜索的延迟时间和费用也会增加。您可以使用 ANN 查找近似 k 最近邻,从而显著缩短延迟时间、降低成本。
在 ANN 搜索中,返回的 k 向量并非真正的 Top-k 最近邻,因为 ANN 搜索会计算近似距离,并且可能不会查看数据集中的所有向量。有时,系统会返回不在前 k 个最近邻中的几个向量。这称为“召回率损失”。您可以接受的召回率损失程度取决于具体应用场景,但在大多数情况下,牺牲一点召回率来换取数据库性能的提升是可接受的权衡。
如需详细了解 Spanner 中支持的近似距离函数,请参阅以下 GoogleSQL 参考页面:
查询向量嵌入
Spanner 通过使用向量索引来加速近似最近邻 (ANN) 向量搜索。您可以使用向量索引来查询向量嵌入。如需查询向量嵌入,您必须先创建向量索引。然后,您可以使用这三个近似距离函数中的任意一个来查找 ANN。
使用近似距离函数时,存在以下限制:
- 近似距离函数必须计算嵌入列与常量表达式(例如,参数或字面量)之间的距离。
- 近似距离函数输出必须在
ORDER BY
子句中用作唯一排序键,并且必须在ORDER BY
后指定LIMIT
。 - 查询必须明确滤除未编入索引的行。在大多数情况下,这意味着查询必须包含与向量索引定义匹配的
WHERE <column_name> IS NOT NULL
子句,除非该列在表定义中已标记为NOT NULL
。
如需查看详细的限制列表,请参阅近似距离函数参考页面。
示例
假设有一个 Documents
表,其中包含一个 DocEmbedding
列(包含根据 DocContents
字节列预计算的文本嵌入)和一个 NullableDocEmbedding
列(从其他来源填充,可能为 null)。
CREATE TABLE Documents (
UserId INT64 NOT NULL,
DocId INT64 NOT NULL,
Author STRING(1024),
DocContents BYTES(MAX),
DocEmbedding ARRAY<FLOAT32> NOT NULL,
NullableDocEmbedding ARRAY<FLOAT32>,
WordCount INT64
) PRIMARY KEY (UserId, DocId);
如需搜索与 [1.0, 2.0, 3.0]
最接近的 100 个向量,请运行以下命令:
SELECT DocId
FROM Documents
WHERE WordCount > 1000
ORDER BY APPROX_EUCLIDEAN_DISTANCE(
ARRAY<FLOAT32>[1.0, 2.0, 3.0], DocEmbedding,
options => JSON '{"num_leaves_to_search": 10}')
LIMIT 100
如果嵌入列可以为 null:
SELECT DocId
FROM Documents
WHERE NullableDocEmbedding IS NOT NULL AND WordCount > 1000
ORDER BY APPROX_EUCLIDEAN_DISTANCE(
ARRAY<FLOAT32>[1.0, 2.0, 3.0], NullableDocEmbedding,
options => JSON '{"num_leaves_to_search": 10}')
LIMIT 100
后续步骤
详细了解 Spanner 向量索引。
详细了解 GoogleSQL
APPROXIMATE_COSINE_DISTANCE()
、APPROXIMATE_EUCLIDEAN_DISTANCE()
、APPROXIMATE_DOT_PRODUCT()
函数。详细了解向量索引最佳实践。
如需查看使用 ANN 的逐步示例,请尝试阅读 Spanner 向量搜索使用入门。