本页介绍了如何使用 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 向量搜索使用入门。