Auf dieser Seite wird erläutert, wie Sie Spanner-Vektorindexe erstellen und verwalten, die die Suche nach dem ungefähren nächsten Nachbarn (Approximate Nearest Neighbor, ANN) und baumbasierte Strukturen verwenden, um die Vektorähnlichkeitssuche für Ihre Daten zu beschleunigen.
Cloud Spanner beschleunigt ANN-Vektorsuchen (Approximate Nearest Neighbor) mithilfe eines speziellen Vektorindex. Dieser Index nutzt Scalable Nearest Neighbor (ScaNN) von Google Research, einen hocheffizienten Algorithmus für die Suche nach dem nächsten Nachbarn.
Der Vektorindex verwendet eine baumartige Struktur, um Daten zu partitionieren und schnellere Suchvorgänge zu ermöglichen. Spanner bietet sowohl zwei- als auch dreistufige Baumkonfigurationen:
- Konfiguration mit zwei Ebenen: Blattknoten (
num_leaves
) enthalten Gruppen von eng verwandten Vektoren zusammen mit dem entsprechenden Zentroid. Die Stammebene besteht aus den Schwerpunkten aller Blattknoten. - Baumkonfiguration mit drei Ebenen: Ähnlich wie bei einem Baum mit zwei Ebenen wird eine zusätzliche Ebene (
num_branches
) eingeführt, aus der die Schwerpunkte der Blattknoten weiter unterteilt werden, um die Stammebene (num_leaves
) zu bilden.
Spanner wählt einen Index für Sie aus. Wenn Sie jedoch wissen, dass ein bestimmter Index am besten funktioniert, können Sie mit dem FORCE_INDEX
-Hinweis den am besten geeigneten Vektorindex für Ihren Anwendungsfall auswählen.
Weitere Informationen finden Sie unter VECTOR INDEX
-Anweisungen.
Beschränkungen
- Vektorindexe können nicht vorab aufgeteilt werden. Weitere Informationen finden Sie unter Übersicht über das Aufteilen von Daten.
Vektorindex erstellen
Zur Optimierung des Rückrufs und der Leistung eines Vektorindex empfehlen wir Folgendes:
Erstellen Sie den Vektorindex, nachdem die meisten Zeilen mit Einbettungen in Ihre Datenbank geschrieben wurden. Möglicherweise müssen Sie den Vektorindex auch regelmäßig neu erstellen, nachdem Sie neue Daten eingefügt haben. Weitere Informationen finden Sie unter Vektorindex neu erstellen.
Mit der Klausel
STORING
können Sie eine Kopie einer Spalte im Vektorindex speichern. Wenn ein Spaltenwert im Vektorindex gespeichert ist, führt Spanner das Filtern auf der Blattebene des Index aus, um die Abfrageleistung zu verbessern. Wir empfehlen, eine Spalte zu speichern, wenn sie in einer Filterbedingung verwendet wird. Weitere Informationen zur Verwendung vonSTORING
in einem Index finden Sie unter Index für reine Indexscans erstellen.
Wenn Sie die Tabelle erstellen, muss die Einbettungsspalte ein Array des Datentyps FLOAT32
(empfohlen) oder FLOAT64
sein und die Annotation vector_length enthalten, die die Dimension der Vektoren angibt.
Mit der folgenden DDL-Anweisung wird eine Tabelle Documents
mit einer Einbettungsspalte DocEmbedding
mit einer Vektorlänge erstellt:
CREATE TABLE Documents (
UserId INT64 NOT NULL,
DocId INT64 NOT NULL,
Author STRING (1024),
DocContents Bytes(MAX),
DocEmbedding ARRAY<FLOAT32>(vector_length=>128) NOT NULL,
NullableDocEmbedding ARRAY<FLOAT32>(vector_length=>128),
WordCount INT64,
) PRIMARY KEY (DocId);
Nachdem Sie die Tabelle Documents
mit Daten gefüllt haben, können Sie einen Vektorindex mit einem zweistufigen Baum und 1.000 Blattknoten für die Tabelle Documents
mit der Einbettungsspalte DocEmbedding
erstellen. Verwenden Sie dazu die Kosinusdistanz:
CREATE VECTOR INDEX DocEmbeddingIndex
ON Documents(DocEmbedding)
STORING (WordCount)
OPTIONS (distance_type = 'COSINE', tree_depth = 2, num_leaves = 1000);
Wenn Ihre Einbettungsspalte in der Tabellendefinition nicht als NOT NULL
gekennzeichnet ist, müssen Sie sie mit einer WHERE COLUMN_NAME IS NOT NULL
-Klausel in der Vektorindexdefinition deklarieren. Dabei ist COLUMN_NAME
der Name Ihrer Einbettungsspalte. So erstellen Sie einen Vektorindex mit einem dreistufigen Baum und 1.000.000 Blattknoten für die Spalte NullableDocEmbedding
mit Nullwerten und Einbettungen mit der Kosinusdistanz:
CREATE VECTOR INDEX DocEmbeddingThreeLevelIndex
ON Documents(NullableDocEmbedding)
STORING (WordCount)
WHERE NullableDocEmbedding IS NOT NULL
OPTIONS (distance_type = 'COSINE', tree_depth = 3, num_branches=1000, num_leaves = 1000000);
Vektorindex filtern
Sie können auch einen gefilterten Vektorindex erstellen, um die ähnlichsten Elemente in Ihrer Datenbank zu finden, die der Filterbedingung entsprechen. Bei einem gefilterten Vektorindex werden nur Zeilen indexiert, die die angegebenen Filterbedingungen erfüllen. Dadurch wird die Suchleistung verbessert.
Im folgenden Beispiel hat die Tabelle Documents2
eine Spalte namens Category
.
In unserer Vektorsuche möchten wir die Kategorie „Tech“ indexieren. Daher erstellen wir eine generierte Spalte, die den Wert NULL
hat, wenn die Kategoriebedingung nicht erfüllt ist.
CREATE TABLE Documents2 (
DocId INT64 NOT NULL,
Category STRING(MAX),
NullIfFiltered BOOL AS (IF(Category = 'Tech', TRUE, NULL)) HIDDEN,
DocEmbedding ARRAY<FLOAT32>(vector_length=>128),
) PRIMARY KEY (DocId);
Als Nächstes erstellen wir einen Vektorindex mit einem Filter. Im TechDocEmbeddingIndex
-Vektorindex werden nur Dokumente in der Kategorie „Tech“ indexiert.
CREATE VECTOR INDEX TechDocEmbeddingIndex
ON Documents2(DocEmbedding)
STORING(NullIfFiltered)
WHERE DocEmbedding IS NOT NULL AND NullIfFiltered IS NOT NULL
OPTIONS (...);
Wenn Spanner die folgende Abfrage ausführt, die Filter enthält, die mit TechDocEmbeddingIndex
übereinstimmen, wird TechDocEmbeddingIndex
automatisch ausgewählt und beschleunigt. Die Abfrage durchsucht nur Dokumente in der Kategorie „Tech“. Sie können auch {@FORCE_INDEX=TechDocEmbeddingIndex}
verwenden, um Spanner zu zwingen, TechDocEmbeddingIndex
explizit zu verwenden.
SELECT *
FROM Documents2
WHERE DocEmbedding IS NOT NULL AND NullIfFiltered IS NOT NULL
ORDER BY APPROX_(....)
LIMIT 10;
Nächste Schritte
Weitere Informationen zu ungefähren nächsten Nachbarn in Spanner
Weitere Informationen zu
VECTOR INDEX
-Anweisungen in GoogleSQL