Auf dieser Seite wird beschrieben, wie Sie mithilfe der ANN-Distanzfunktionen (Approximate Nearest Neighbor) Vektoreinbettungen finden und abfragen.
Bei einem kleinen Datensatz können Sie K-Nearest Neighbors (KNN) verwenden, um die genauen k-nächsten Vektoren zu finden. Mit zunehmender Größe des Datensatzes steigen jedoch auch die Latenz und die Kosten einer KNN-Suche. Mit ANN können Sie die ungefähren k-nächsten Nachbarn mit deutlich geringerer Latenz und zu geringeren Kosten finden.
Bei einer ANN-Suche sind die k zurückgegebenen Vektoren nicht die tatsächlichen k nächsten Nachbarn, da bei der ANN-Suche ungefähre Distanzen berechnet werden und möglicherweise nicht alle Vektoren im Datensatz berücksichtigt werden. Gelegentlich werden einige Vektoren zurückgegeben, die nicht zu den k nächsten Nachbarn gehören. Dies wird als Recall-Verlust bezeichnet. Wie viel Trefferquotenverlust für Sie akzeptabel ist, hängt vom Anwendungsfall ab. In den meisten Fällen ist es jedoch ein akzeptabler Kompromiss, etwas Trefferquote im Gegenzug für eine verbesserte Datenbankleistung zu verlieren.
Weitere Informationen zu den in Spanner unterstützten Funktionen für die ungefähre Distanz finden Sie auf den folgenden Referenzseiten für Ihren Datenbankdialekt:
- GoogleSQL
- PostgreSQL
Vektoreinbettungen abfragen
Cloud Spanner beschleunigt die Suche nach ANN-Vektoren (Approximate Nearest Neighbor) mithilfe eines Vektorindex. Sie können einen Vektorindex verwenden, um Vektoreinbettungen abzufragen. Wenn Sie Vektoreinbettungen abfragen möchten, müssen Sie zuerst einen Vektorindex erstellen. Anschließend können Sie eine der drei ungefähren Distanzfunktionen verwenden, um den ANN zu finden.
Bei der Verwendung der Funktionen für die ungefähre Distanz gelten die folgenden Einschränkungen:
- Die Funktion für die ungefähre Distanz muss die Distanz zwischen einer Spalte mit Einbettungen und einem konstanten Ausdruck (z. B. einem Parameter oder einem Literal) berechnen.
- Die Ausgabe der Funktion für die ungefähre Distanz muss in einer
ORDER BY-Klausel als einziger Sortierschlüssel verwendet werden und nach derORDER BYmuss eineLIMITangegeben werden. - In der Abfrage müssen Zeilen, die nicht indexiert sind, explizit herausgefiltert werden. In den meisten Fällen muss die Abfrage eine
WHERE <column_name> IS NOT NULL-Klausel enthalten, die der Vektorindexdefinition entspricht, es sei denn, die Spalte ist in der Tabellendefinition bereits alsNOT NULLgekennzeichnet.
Eine detaillierte Liste der Einschränkungen finden Sie auf der Referenzseite für die Funktion für die ungefähre Distanz.
Beispiele
Angenommen, Sie haben eine Tabelle Documents mit einer Spalte DocEmbedding mit vorab berechneten Texteinbettungen aus der Spalte DocContents (Bytes) und einer Spalte NullableDocEmbedding, die aus anderen Quellen stammt und möglicherweise NULL-Werte enthält.
GoogleSQL
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);
PostgreSQL
CREATE TABLE documents (
user_id bigint not null,
doc_id bigint not null,
author varchar(1024),
doc_contents bytea,
doc_embedding float4[] not null,
nullable_doc_embedding float4[],
word_count bigint,
PRIMARY KEY (user_id, doc_id)
);
Wenn Sie nach den 100 Vektoren suchen möchten, die [1.0, 2.0, 3.0] am nächsten sind, geben Sie eine der folgenden Suchoptionen in der ungefähren Distanzfunktion an:
num_leaves_to_search: Die Anzahl der zu durchsuchenden Blätter. Der Wert muss eine positive Ganzzahl sein.pct_leaves_to_search: Der Prozentsatz der zu durchsuchenden Blätter. Der Wert muss eine Double-Zahl zwischen0.0und100.0mit einem expliziten Dezimaltrennzeichen sein (z. B.10.0). Vektorindexe, die vor November 2025 erstellt wurden, unterstützen diese Suchoption möglicherweise nicht.
Sie können nicht beide Optionen in derselben Funktion für die ungefähre Distanz angeben.
Option 1: Suchoption num_leaves_to_search verwenden
GoogleSQL
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
PostgreSQL
SELECT doc_id
FROM documents
WHERE word_count > 1000
ORDER BY spanner.approx_euclidean_distance(
ARRAY[1.0, 2.0, 3.0]::float4[], doc_embedding,
options=>jsonb'{"num_leaves_to_search": 10}'
)
LIMIT 100;
Option 2: Suchoption pct_leaves_to_search verwenden
GoogleSQL
SELECT DocId
FROM Documents
WHERE WordCount > 1000
ORDER BY APPROX_EUCLIDEAN_DISTANCE(
ARRAY<FLOAT32>[1.0, 2.0, 3.0], DocEmbedding,
options => JSON '{"pct_leaves_to_search": 10.0}')
LIMIT 100
PostgreSQL
SELECT doc_id
FROM documents
WHERE word_count > 1000
ORDER BY spanner.approx_euclidean_distance(
ARRAY[1.0, 2.0, 3.0]::float4[], doc_embedding,
options=>jsonb'{"pct_leaves_to_search": 10.0}'
)
LIMIT 100;
Wenn Sie nach den 100 Vektoren suchen möchten, die einer Einbettung am nächsten sind, die von einem SQL-Ausdruck generiert wird, verwenden Sie das folgende Muster. In diesem Beispiel werden mit der Abfrage die Dokumente gesucht, die der Einbettung von UserId = 1 und DocId = 1 am ähnlichsten sind:
GoogleSQL
WITH emb AS (
SELECT DocEmbedding AS value
FROM Documents
WHERE UserId = 1 AND DocId = 1
LIMIT 1
)
SELECT DocId
FROM Documents, emb
ORDER BY APPROX_EUCLIDEAN_DISTANCE(
emb.value, DocEmbedding,
options => JSON '{"num_leaves_to_search": 10}')
LIMIT 100
PostgreSQL
SELECT documents.doc_id
FROM
documents,
(
SELECT doc_embedding AS value
FROM documents
WHERE user_id = 1 AND doc_id = 1
LIMIT 1
) vector
WHERE documents.doc_embedding IS NOT NULL
ORDER BY spanner.APPROX_EUCLIDEAN_DISTANCE(documents.doc_embedding,
vector.value, options=>'{"num_leaves_to_search": 10}'::jsonb)
LIMIT 100
Wenn die Einbettungsspalte Nullwerte enthalten kann:
GoogleSQL
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
PostgreSQL
SELECT doc_id
FROM documents
WHERE nullable_doc_embedding IS NOT NULL AND word_count > 1000
ORDER BY spanner.approx_euclidean_distance(
ARRAY[1.0, 2.0, 3.0]::float4[], nullable_doc_embedding,
options=>jsonb'{"num_leaves_to_search": 10}'
)
LIMIT 100;
Entfernung zu den Abfrageergebnissen hinzufügen
In den vorherigen Beispielen wird die ANN-Distanz verwendet, um die Abfrageergebnisse zu sortieren, sie wird aber nicht in den Ergebnissen angezeigt. Wenn Sie die Entfernung zu den Ergebnissen hinzufügen möchten, platzieren Sie die Entfernungsfunktion in der SELECT-Klausel und weisen Sie ihr einen Alias zu. Verwenden Sie diesen Alias dann als einzigen Sortierschlüssel in der ORDER BY-Klausel.
Beispiele
GoogleSQL
SELECT DocId,
APPROX_EUCLIDEAN_DISTANCE(
ARRAY<FLOAT32>[1.0, 2.0, 3.0], NullableDocEmbedding,
options => JSON '{"num_leaves_to_search": 10}') AS distance
FROM Documents
WHERE NullableDocEmbedding IS NOT NULL AND WordCount > 1000
ORDER BY distance
LIMIT 100
PostgreSQL
SELECT doc_id,
spanner.approx_euclidean_distance(
ARRAY[1.0, 2.0, 3.0]::float4[], nullable_doc_embedding,
options=>jsonb'{"num_leaves_to_search": 10}'
) AS distance
FROM documents
WHERE nullable_doc_embedding IS NOT NULL AND word_count > 1000
ORDER BY distance
LIMIT 100;
Nächste Schritte
Weitere Informationen zu Indexanweisungen für GoogleSQL
VECTOR INDEXund PostgreSQLINDEXErste Schritte mit der Spanner-Vektorsuche – hier finden Sie ein Schritt-für-Schritt-Beispiel für die Verwendung von ANN.