Vektorindexe erstellen und verwalten

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

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 von STORING 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