Ungefähre nächste Nachbarn finden, um Vektoreinbettungen in Spanner zu indexieren und abzufragen

Auf dieser Seite wird beschrieben, wie Sie einen Vektorindex erstellen und Vektoreinbettungen anhand unter Verwendung der ungefähren Kosinus-Distanz, der ungefähren euklidischen Distanz und ungefähren Punktproduktvektorfunktionen. Sie können diese können Sie die ungefähren nächsten Nachbarn (ANN) in Spanner ermitteln. Wenn ein Dataset klein ist, können Sie K-nächste Nachbarn (KNN) verwenden. um die genauen k-nächsten Vektoren zu finden. Wenn Ihr Dataset jedoch wächst, erhöht sich die Latenz und die Kosten einer KNN-Suche steigen ebenfalls. Mit ANN können Sie die ungefähren k-nächsten Nachbarn mit deutlich reduzierter Latenz und Kosten ermitteln.

Ungefähre k-nächste Nachbarn

Bei einer ANN-Suche sind die k-zurückgegebenen Vektoren nicht die wirklichen obersten k-nächsten Vektoren. und Nachbarn. Gelegentlich können ein paar Vektoren, die nicht zu den obersten k-nächstgelegenen Nachbarn zurückgegeben. Das wird als Rückrufverlust bezeichnet. Wie groß der Verlust der Abrufquote für Sie akzeptabel ist, hängt vom Anwendungsfall ab. In den meisten Fällen ist es jedoch ein akzeptabler Kompromiss, wenn Sie einen kleinen Verlust der Abrufquote im Austausch für eine verbesserte Datenbankleistung in Kauf nehmen.

Weitere Informationen zu den Funktionen für ungefähre Entfernungen in Spanner finden Sie unter:

Vektorindex

Spanner beschleunigt die ANN-Vektorsuche mithilfe einer Vektorindex. Dieser Index nutzt den Scalable Nearest Neighbor (ScaNN) von Google Research, einen hocheffizienten Algorithmus für die Suche nach dem nächsten Nachbarn.

Der Vektorindex verwendet eine baumbasierte Struktur, um Daten zu partitionieren und schnellere Suchanfragen zu ermöglichen. Spanner bietet sowohl zwei- als auch dreistufige Baumkonfigurationen:

  • Zweistufige Baumkonfiguration: Endknoten (num_leaves) enthalten Gruppen eng miteinander verwandter Vektoren sowie deren entsprechenden Schwerpunkt. Die Wurzelebene besteht aus den Schwerpunkten aller Blattknoten.
  • Baumkonfiguration auf drei Ebenen: Dies ähnelt dem Konzept einer zweistufigen Baumstruktur, während Eine zusätzliche Zweigebene (num_branches) wird eingeführt, von welchem Blattknoten aus Schwerpunkte werden weiter partitioniert, um die Stammebene (num_leaves) zu bilden.

Außerdem müssen Sie Ihren Vektorindex mit einem bestimmten Entfernungsmesswert erstellen. Sie können den für Ihren Anwendungsfall am besten geeigneten Entfernungsmesswert auswählen, indem Sie distance_type auf einen der Werte COSINE, DOT_PRODUCT oder EUCLIDEAN festlegen.

Weitere Informationen findest du unter VECTOR INDEX-Anweisungen.

Beschränkungen

Für den Spanner-Vektorindex gelten die folgenden Einschränkungen:

  • ALTER VECTOR INDEX wird nicht unterstützt.

Vektorindex erstellen

Zur Optimierung des Vektorindex für eine gute Trefferquote und Leistung empfehlen wir dass Sie Ihren Vektorindex erstellen, nachdem die meisten Zeilen mit Einbettungen in Ihre Datenbank geschrieben. Möglicherweise müssen Sie auch regelmäßig den Vektorindex neu zu erstellen, nachdem Sie neue Daten eingefügt haben. Weitere Informationen finden Sie unter Erstellen Sie den Vektorindex neu.

So erstellen Sie einen Vektorindex mit einem zweistufigen Baum und 1.000 Blattknoten in einer Documents-Tabelle mit einer Einbettungsspalte DocEmbedding unter Verwendung des Kosinusabstands:

CREATE VECTOR INDEX DocEmbeddingIndex
  ON Documents(DocEmbedding)
  OPTIONS (distance_type = 'COSINE', tree_depth = 2, num_leaves = 1000);

So erstellen Sie einen Vektorindex mit einem dreistufigen Baum und 1.000.000 Blattknoten:

CREATE VECTOR INDEX DocEmbeddingIndex
  ON Documents(NullableDocEmbedding)
  WHERE NullableDocEmbedding IS NOT NULL
  OPTIONS (distance_type = 'COSINE', tree_depth = 3, num_branches=1000, num_leaves = 1000000);

Wenn für die Einbettungsspalte Nullwerte zulässig sind, müssen Sie sie mit einem WHERE column_name IS NOT NULL-Klausel:

CREATE VECTOR INDEX DocEmbeddingIndex
  ON Documents(NullableDocEmbedding)
  WHERE NullableDocEmbedding IS NOT NULL
  OPTIONS (distance_type = 'COSINE', tree_depth = 2, num_leaves = 1000);

Vektoreinbettungen abfragen

Verwenden Sie eine der drei Näherungsfunktionen für die Entfernung, um einen Vektorindex abzufragen:

  • APPROX_COSINE_DISTANCE
  • APPROX_EUCLIDEAN_DISTANCE
  • APPROX_DOT_PRODUCT

Zu den Einschränkungen bei der Verwendung der Funktionen für ungefähre Entfernungen gehören: Folgendes:

  • Sie müssen einen Abfragehinweis angeben, um den Vektorindex zu verwenden.
  • Sie müssen einen konstanten Ausdruck als ein Argument der Entfernungsfunktion verwenden. (z. B. ein Parameter oder ein Literal).
  • Die Abfrage oder untergeordnete Abfrage, in der die Funktion „Etwaige Entfernung“ verwendet wird, muss eine bestimmte Form haben: Die Entfernungsfunktion muss der einzige ORDER BY-Schlüssel sein und es muss ein Limit angegeben werden.

Eine detaillierte Liste der Einschränkungen finden Sie in der Referenzseite für die Funktion „Ungefähre Entfernung“.

Beispiel

So suchen Sie nach den nächsten 100 Vektoren, die [1.0, 2.0, 3.0] entsprechen:

SELECT DocId
FROM Documents@{FORCE_INDEX=DocEmbeddingIndex}
ORDER BY APPROX_EUCLIDEAN_DISTANCE(
  ARRAY<FLOAT32>[1.0, 2.0, 3.0], DocEmbedding,
  options => JSON '{"num_leaves_to_search": 10}')
LIMIT 100

Wenn für die Einbettungsspalte Nullwerte zulässig sind:

SELECT DocId
FROM Documents@{FORCE_INDEX=DocEmbeddingIndex}
WHERE NullableDocEmbedding IS NOT NULL
ORDER BY APPROX_EUCLIDEAN_DISTANCE(
  ARRAY<FLOAT32>[1.0, 2.0, 3.0], NullableDocEmbedding,
  options => JSON '{"num_leaves_to_search": 10}')
LIMIT 100

Best Practices

Befolgen Sie diese Best Practices, um Ihre Vektorindexe zu optimieren und die Abfrage zu verbessern Ergebnisse.

Vektorsuchoptionen optimieren

Der optimale Wert für die Vektorsuche hängt vom Anwendungsfall, dem Vektordatensatz und den Abfragevektoren ab. Möglicherweise müssen Sie die Parameter iterativ optimieren, um die besten Werte für Ihre spezifische Arbeitslast zu finden.

Hier sind einige hilfreiche Richtlinien, die Sie bei der Auswahl geeigneter Werte beachten sollten:

  • tree_depth (Baumebene): Wenn die indexierte Tabelle weniger als 10 Millionen Zeilen hat, verwenden Sie 2 als tree_depth. Andernfalls werden mit einem tree_depth von 3 Tabellen mit bis zu etwa 10 Milliarden Zeilen unterstützt.

  • num_leaves: Verwendet die Quadratwurzel der Zeilenanzahl im Dataset. Ein höherer Wert kann die Erstellungszeit des Vektorindexes verlängern. num_leaves nicht festlegen größer als table_row_count/1000, da dies zu kleinen Blättern und schlechte Leistung.

  • num_leaves_to_search: Diese Option gibt an, wie viele Blattknoten des Index vorhanden sind. nach denen gesucht wird. Durch eine Erhöhung von num_leaves_to_search wird der Recall verbessert, aber auch die Latenz und die Kosten. Wir empfehlen, als Wert für num_leaves_to_search eine Zahl zu verwenden, die 1 % der Gesamtzahl der Blätter entspricht, die in der CREATE VECTOR INDEX-Anweisung definiert sind. Wenn Sie eine Filterklausel verwenden, um die Suche zu erweitern.

Wenn ein akzeptabler Recall erreicht wird, die Abfrage aber zu hoch ist, zu einer niedrigen maximalen Anzahl von Abfragen pro Sekunde führen. Erhöhen Sie den num_leaves, indem Sie Schritte:

  1. Legen Sie num_leaves auf ein Vielfaches k des ursprünglichen Werts fest (z. B. 2 * sqrt(table_row_count)).
  2. Legen Sie für num_leaves_to_search das gleiche Vielfache der k-Werte seines ursprünglichen Werts fest.
  3. Probieren Sie, num_leaves_to_search zu reduzieren, um Kosten und Abfragen pro Sekunde zu verbessern und gleichzeitig die Recall-Funktion aufrechterhalten.

Erinnerung verbessern

Es gibt mehrere Möglichkeiten für eine Verschlechterung der Erinnerung, darunter:

  • num_leaves_to_search ist zu klein: Bei einigen Abfragevektoren ist es möglicherweise schwieriger, die nächsten Nachbarn zu finden. Wenn Sie num_leaves_to_search erhöhen, um mehr Blätter zu durchsuchen, kann sich die Trefferquote verbessern. Zuletzt verwendet Abfragen möglicherweise umgeschwenkt haben, um mehr dieser anspruchsvollen Vektoren einzubeziehen.

  • Der Vektorindex muss neu erstellt werden: Die Baumstruktur des Vektorindexes wird beim Erstellen für den Datensatz optimiert und ist danach statisch. Werden deutlich unterschiedliche Vektoren hinzugefügt, nachdem der Vektorindex ist, ist die Baumstruktur möglicherweise nicht optimal, sodass eine schlechtere Trefferquote.

Vektorindex neu erstellen

So erstellen Sie Ihren Vektorindex ohne Ausfallzeit neu:

  1. Erstellen Sie einen neuen Vektorindex in derselben Einbettungsspalte wie der aktuelle Vektor. Index erstellen und Parameter (z. B. OPTIONS) nach Bedarf aktualisieren.
  2. Nachdem die Indexerstellung abgeschlossen ist, ändern Sie den FORCE_INDEX-Hinweis so, dass er auf den neuen Index verweist, um die Vektorsuchabfrage zu aktualisieren. Dadurch wird sichergestellt, dass die Abfrage den neuen Vektorindex verwendet. (Möglicherweise müssen Sie Ihr num_leaves_to_search in der neuen Abfrage ein.
  3. Löschen Sie den veralteten Vektorindex.

Nächste Schritte