ScaNN-Index erstellen

Auf dieser Seite wird beschrieben, wie Sie gespeicherte Einbettungen verwenden, um Indexe zu generieren und Einbettungen mit dem ScaNN-Index in AlloyDB for PostgreSQL abzufragen. Weitere Informationen zum Speichern von Einbettungen finden Sie unter Vektoreinbettungen speichern.

AlloyDB alloydb_scann, eine von Google entwickelte PostgreSQL-Erweiterung, die einen hocheffizienten Index für die Suche nach dem nächsten Nachbarn implementiert, der auf dem ScaNN-Algorithmus basiert.

Der ScaNN-Index ist ein baumbasierter Quantisierungsindex für die Suche nach dem ungefähren nächsten Nachbarn. Im Vergleich zu HNSW ist die Indexerstellung schneller und der Speicherbedarf geringer. Außerdem bietet es im Vergleich zu HNSW je nach Arbeitslast eine höhere Abfragerate pro Sekunde.

Hinweise

Bevor Sie mit dem Erstellen von Indexen beginnen können, müssen Sie die folgenden Voraussetzungen erfüllen.

  • Einbettungsvektoren wurden einer Tabelle in Ihrer AlloyDB-Datenbank hinzugefügt.

  • Die vector-Erweiterung, die auf pgvector basiert und von Google für AlloyDB erweitert wurde, und die alloydb_scann-Erweiterung sind installiert:

    CREATE EXTENSION IF NOT EXISTS alloydb_scann CASCADE;
    
  • Wenn Sie automatisch optimierte ScaNN-Indizes erstellen möchten, muss das Flag scann.enable_preview_features aktiviert sein. Wenn Sie keine Vorschaufunktionen aktivieren möchten oder eine Produktionsinstanz verwenden, können Sie stattdessen einen ScaNN-Index mit bestimmten Parametern erstellen.

Automatisch optimierten ScaNN-Index erstellen

Mit der Funktion „Auto Index“ können Sie die Indexerstellung vereinfachen, indem Sie automatisch Indexe erstellen lassen, die für die Suchleistung oder für ein ausgewogenes Verhältnis zwischen Indexerstellungszeit und Suchleistung optimiert sind.

Wenn Sie den Modus AUTO verwenden, müssen Sie nur den Tabellennamen und die Spalte mit den Einbettungen sowie die Distanzfunktion angeben, die Sie verwenden möchten. Sie können den Index für die Suchleistung optimieren oder ein Gleichgewicht zwischen Indexerstellungszeiten und Suchleistung herstellen.

Sie können auch den Modus MANUAL verwenden, um Indexe mit detaillierter Steuerung anderer Parameter für die Indexoptimierung zu erstellen.

ScaNN-Index im AUTO-Modus erstellen

Beachten Sie vor dem Erstellen von Indexen im AUTO-Modus Folgendes:

  • AlloyDB kann keinen ScaNN-Index für Tabellen mit unzureichenden Daten erstellen.
  • Sie können keine Parameter für die Indexerstellung wie num_leaves festlegen, wenn Sie Indexe im Modus AUTO erstellen.
  • Die automatische Wartung ist standardmäßig für alle im AUTO-Modus erstellten Indexe aktiviert.

Wenn Sie einen Index im AUTO-Modus erstellen möchten, aktivieren Sie das Feature-Flag scann.enable_zero_knob_index_creation. Dadurch wird die automatische Wartung aktiviert. Führen Sie nach dem Aktivieren des Flags den folgenden Befehl aus:

  CREATE INDEX INDEX_NAME ON TABLE
  USING scann (EMBEDDING_COLUMN DISTANCE_FUNCTION)
  WITH (mode='AUTO');

Ersetzen Sie Folgendes:

  • INDEX_NAME: Der Name des Index, den Sie erstellen möchten, z. B. my-scann-index. Die Indexnamen sind in Ihrer Datenbank freigegeben. Prüfen Sie, ob jeder Indexname für jede Tabelle in Ihrer Datenbank eindeutig ist.

  • TABLE: Die Tabelle, der der Index hinzugefügt werden soll.

  • EMBEDDING_COLUMN: die Spalte, in der vector-Daten gespeichert werden.

  • DISTANCE_FUNCTION: Die Distanzfunktion, die für diesen Index verwendet werden soll. Wählen Sie eine der folgenden Optionen aus:

    • L2-Distanz: l2

    • Skalarprodukt: dot_product

    • Kosinus-Distanz: cosine

  • OPTIMIZATION (optional): Standardmäßig wird ein für die Suche optimierter Index erstellt. Geben Sie dafür einen der folgenden Werte an: .

    • SEARCH_OPTIMIZED (Standard): Optimiert sowohl die Trefferquote als auch die Latenz der Vektorsuche. Die Indexerstellung dauert jedoch länger.
    • BALANCED: zum Erstellen eines Index, bei dem die Indexerstellungszeit und die Suchleistung ausgewogen sind.

ScaNN-Index im Modus „MANUAL“ erstellen

Wenn Sie das Flag scann.enable_preview_features aktiviert haben und die Optimierungsparameter genau steuern möchten, können Sie den Index im Modus MANUAL erstellen.

Führen Sie den folgenden Befehl aus, um einen ScaNN-Index im MANUAL-Modus zu erstellen:

  CREATE INDEX INDEX_NAME ON TABLE
  USING scann (EMBEDDING_COLUMN DISTANCE_FUNCTION)
  WITH (mode='MANUAL', num_leaves=NUM_LEAVES_VALUE, quantizer =QUANTIZER, max_num_levels=MAX_NUM_LEVELS);

Ersetzen Sie Folgendes:

  • INDEX_NAME: Der Name des Index, den Sie erstellen möchten, z. B. my-scann-index. Die Indexnamen sind in Ihrer Datenbank freigegeben. Prüfen Sie, ob jeder Indexname für jede Tabelle in Ihrer Datenbank eindeutig ist.

  • TABLE: Die Tabelle, der der Index hinzugefügt werden soll.

  • EMBEDDING_COLUMN: die Spalte, in der vector-Daten gespeichert werden.

  • DISTANCE_FUNCTION: Die Distanzfunktion, die für diesen Index verwendet werden soll. Wählen Sie eine der folgenden Optionen aus:

    • L2-Distanz: l2

    • Skalarprodukt: dot_product

    • Kosinus-Distanz: cosine

  • NUM_LEAVES_VALUE: Die Anzahl der Partitionen, die auf diesen Index angewendet werden sollen. Kann auf einen beliebigen Wert zwischen 1 und 10 Millionen festgelegt werden. Weitere Informationen dazu, wie Sie diesen Wert festlegen, finden Sie unter ScaNN-Index abstimmen.

  • QUANTIZER: Der zu verwendende Quantisierungstyp. Folgende Optionen sind verfügbar:

    • SQ8: Bietet ein ausgewogenes Verhältnis zwischen Abfrageleistung und minimalem Recall-Verlust, in der Regel weniger als 1–2%. Dies ist der Standardwert.
    • AH: Diese Option kann die Abfrageleistung potenziell verbessern, wenn die spaltenorientierte Engine aktiviert ist und Ihre Index- und Tabellendaten in die spaltenorientierte Engine eingefügt werden, sofern die konfigurierte Größe dies zulässt. AH ist im Vergleich zu SQ8 bis zu viermal komprimiert. Weitere Informationen finden Sie unter Best Practices für die Optimierung von ScaNN.
    • FLAT: Bietet den höchsten Recall von 99% oder höher, allerdings auf Kosten der Suchleistung.
  • MAX_NUM_LEVELS: die maximale Anzahl von Ebenen im K-Means-Clustering-Baum. Legen Sie 1(Standard) für die zweistufige baumbasierte Quantisierung und 2 für die dreistufige baumbasierte Quantisierung fest.

Sie können weitere Parameter für die Indexerstellung oder die Abfrage-Laufzeit hinzufügen, um Ihren Index zu optimieren. Weitere Informationen finden Sie unter ScaNN-Index abstimmen.

ScaNN-Index mit bestimmten Parametern erstellen

Wenn Ihre Anwendung spezifische Anforderungen an die Rückruf- und Indexerstellungszeiten hat, können Sie den Index manuell erstellen. Sie können je nach Arbeitslast einen zwei- oder dreistufigen Baumindex erstellen. Weitere Informationen zum Abstimmen von Parametern finden Sie unter ScaNN-Index abstimmen.

Zweistufiger Baumindex

Wenn Sie einen zweistufigen Baumindex mit dem ScaNN-Algorithmus auf eine Spalte mit gespeicherten Vektoreinbettungen anwenden möchten, führen Sie die folgende DDL-Abfrage aus:

CREATE INDEX INDEX_NAME ON TABLE
USING scann (EMBEDDING_COLUMN DISTANCE_FUNCTION)
WITH (num_leaves=NUM_LEAVES_VALUE, quantizer =QUANTIZER);

Ersetzen Sie Folgendes:

  • INDEX_NAME: Der Name des Index, den Sie erstellen möchten, z. B. my-scann-index. Die Indexnamen sind in Ihrer Datenbank freigegeben. Achten Sie darauf, dass jeder Indexname für jede Tabelle in Ihrer Datenbank eindeutig ist.

  • TABLE: Die Tabelle, der der Index hinzugefügt werden soll.

  • EMBEDDING_COLUMN: eine Spalte, in der vector-Daten gespeichert werden.

  • DISTANCE_FUNCTION: Die Distanzfunktion, die für diesen Index verwendet werden soll. Wählen Sie eine der folgenden Optionen aus:

    • L2-Distanz: l2

    • Skalarprodukt: dot_product

    • Kosinus-Distanz: cosine

  • NUM_LEAVES_VALUE: Die Anzahl der Partitionen, die auf diesen Index angewendet werden sollen. Kann auf einen beliebigen Wert zwischen 1 und 10 Millionen festgelegt werden. Weitere Informationen dazu, wie Sie diesen Wert festlegen, finden Sie unter ScaNN-Index abstimmen.

  • QUANTIZER: Der zu verwendende Quantisierungstyp. Folgende Optionen sind verfügbar:

    • SQ8: Bietet ein ausgewogenes Verhältnis zwischen Abfrageleistung und minimalem Recall-Verlust, in der Regel weniger als 1–2%. Dies ist der Standardwert.
    • AH: Diese Option kann die Abfrageleistung potenziell verbessern, wenn die spaltenorientierte Engine aktiviert ist und Ihre Index- und Tabellendaten in die spaltenorientierte Engine eingefügt werden, sofern die konfigurierte Größe dies zulässt. AH ist im Vergleich zu SQ8 bis zu viermal komprimiert. Weitere Informationen finden Sie unter Best Practices für die Optimierung von ScaNN.
    • FLAT: Bietet den höchsten Recall von 99% oder höher, allerdings auf Kosten der Suchleistung.

Baumindex mit drei Ebenen

Wenn Sie einen dreistufigen Baumindex mit dem ScaNN-Algorithmus auf eine Spalte mit gespeicherten Vektoreinbettungen anwenden möchten, führen Sie die folgende DDL-Abfrage aus:

CREATE INDEX INDEX_NAME ON TABLE
  USING scann (EMBEDDING_COLUMN DISTANCE_FUNCTION)
  WITH (num_leaves=NUM_LEAVES_VALUE, max_num_levels = 2);

Nachdem Sie den Index erstellt haben, können Sie Abfragen zur Suche nach nächsten Nachbarn ausführen, die den Index verwenden. Folgen Sie dazu der Anleitung unter Abfrage von nächsten Nachbarn mit einem vorgegebenen Text erstellen.

Die Indexparameter müssen mit Blick auf ein gutes Gleichgewicht zwischen QPS und Recall festgelegt werden. Weitere Informationen zum Abstimmen des ScaNN-Index finden Sie unter ScaNN-Index abstimmen.

Wenn Sie diesen Index für eine Einbettungsspalte erstellen möchten, die den Datentyp real[] anstelle von vector verwendet, wandeln Sie die Spalte in den Datentyp vector um:

CREATE INDEX INDEX_NAME ON TABLE
USING scann (CAST(EMBEDDING_COLUMN AS vector(DIMENSIONS)) DISTANCE_FUNCTION)
WITH (num_leaves=NUM_LEAVES_VALUE, max_num_levels = MAX_NUM_LEVELS);

Ersetzen Sie DIMENSIONS durch die dimensionale Breite der Einbettungsspalte. Weitere Informationen zum Ermitteln der Dimensionen finden Sie unter der Funktion vector_dims in Vektorfunktionen.

Aktivieren Sie für eine konsistente Suche die automatische Wartung, wenn Sie einen ScaNN-Index erstellen. Weitere Informationen finden Sie unter Vektorindexe verwalten. Dieses Feature ist in der Vorschau verfügbar.

Verwenden Sie zum Anzeigen des Indexierungsfortschritts die pg_stat_progress_create_index-Ansicht:

SELECT * FROM pg_stat_progress_create_index;

In der Spalte phase sehen Sie den aktuellen Status der Indexerstellung. Nach Abschluss der Indexerstellung ist die Zeile für den Index nicht mehr sichtbar.

Informationen zum Abstimmen des Index für ein bestimmtes Gleichgewicht zwischen durchschnittlichem Recall und QPS finden Sie unter ScaNN-Index abstimmen.

Erzwingen der Indexerstellung für leere oder kleine Tabellen

AlloyDB enthält Validierungen, um die Erstellung eines ScaNN-Index für eine leere Tabelle oder eine Tabelle mit sehr wenigen Zeilen zu verhindern, da dies zu einer suboptimalen Leistung führen kann. In einigen Entwicklungs- oder Testszenarien müssen Sie jedoch möglicherweise einen Index für eine leere oder kleine Tabelle erstellen. In diesen Fällen können Sie die Indexerstellung erzwingen.

So erzwingen Sie die Indexgenerierung:

  1. Legen Sie den Parameter scann.allow_blocked_operations creation auf Sitzungsebene in der Datenbank auf true fest:

    SET scann.allow_blocked_operations = true;
    
  2. Weisen Sie dem Nutzer, der diese Abfragen in der Datenbank ausführt, die Berechtigung SUPERUSER zu:

    CREATE USER USER_NAME WITH SUPERUSER PASSWORD PASSWORD;
    

    Ersetzen Sie Folgendes:

    • USER_NAME: der Name des Nutzers, dem Sie die Berechtigung gewähren möchten.
    • PASSWORD: das Passwort des Nutzers.

Indexe parallel erstellen

Je nach Dataset und Art des Index, den Sie erstellen möchten, kann AlloyDB automatisch mehrere parallele Worker starten, um den Index schneller zu erstellen.

Die parallele Indexerstellung wird häufig ausgelöst, wenn Sie einen ScaNN-Index mit drei Ebenen erstellen oder Ihr Dataset mehr als 100 Millionen Zeilen umfasst.

Obwohl AlloyDB die Anzahl der parallelen Worker automatisch optimiert, können Sie die parallelen Worker mit den PostgreSQL-Parametern für die Abfrageplanung max_parallel_maintenance_workers, max_parallel_workers und min_parallel_table_scan_size anpassen.

Abfrage ausführen

Nachdem Sie die Einbettungen in Ihrer Datenbank gespeichert und indexiert haben, können Sie mit dem Abfragen Ihrer Daten beginnen. Mit der alloydb_scann-Erweiterung können keine Bulk-Suchanfragen ausgeführt werden.

Wenn Sie die semantisch nächsten Nachbarn für einen Einbettungsvektor finden möchten, können Sie die folgende Beispielabfrage ausführen. Dabei legen Sie dieselbe Distanzfunktion fest, die Sie beim Erstellen des Index verwendet haben.

  SELECT * FROM TABLE
  ORDER BY EMBEDDING_COLUMN DISTANCE_FUNCTION_QUERY 'EMBEDDING'
  LIMIT ROW_COUNT

Ersetzen Sie Folgendes:

  • TABLE: Die Tabelle, die die Einbettung enthält, mit der der Text verglichen werden soll.

  • INDEX_NAME: Der Name des Index, den Sie verwenden möchten, z. B. my-scann-index.

  • EMBEDDING_COLUMN: die Spalte mit den gespeicherten Einbettungen.

  • DISTANCE_FUNCTION_QUERY: Die Distanzfunktion, die für diese Abfrage verwendet werden soll. Wählen Sie je nach der beim Erstellen des Index verwendeten Distanzfunktion eine der folgenden Optionen aus:

    • L2-Distanz: <->

    • Inneres Produkt:<#>

    • Kosinus-Distanz: <=>

  • EMBEDDING: Der Einbettungsvektor, für den Sie die nächsten gespeicherten semantischen Nachbarn finden möchten.

  • ROW_COUNT: Die Anzahl der zurückzugebenden Zeilen.

    Geben Sie 1 an, wenn Sie nur das beste Ergebnis erhalten möchten.

Sie können auch die Funktion embedding() verwenden, um den Text in einen Vektor zu übersetzen. Da embedding() ein real-Array zurückgibt, müssen Sie den embedding()-Aufruf explizit in vector umwandeln, bevor Sie ihn auf einen der Nearest-Neighbor-Operatoren anwenden (z.B. <-> für die L2-Distanz). Diese Operatoren können dann den ScaNN-Index verwenden, um die Datenbankzeilen mit den semantisch ähnlichsten Einbettungen zu finden.

Nächste Schritte