ScaNN-Index erstellen

Auf dieser Seite wird beschrieben, wie Sie gespeicherte Einbettungen verwenden, um ScaNN-Indizes zu generieren und Einbettungen mit 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 werden 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.
  • Automatische Wartung ist standardmäßig für alle im AUTO-Modus erstellten Indexe aktiviert.

Wenn Sie einen Index im Modus AUTO erstellen möchten, aktivieren Sie zuerst das Feature-Flag scann.zero_knob_index_creation. 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', optimization='OPTIMIZATION');

Ersetzen Sie Folgendes:

  • INDEX_NAME: der Name des Index, den Sie erstellen möchten, z. B. my-scann-index. Die Indexnamen werden für Ihre 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: Legen Sie dafür Folgendes fest:

    • SEARCH_OPTIMIZED: um sowohl den Rückruf der Vektorsuche als auch die Latenz der Vektorsuche zu optimieren. Dies führt jedoch zu einer längeren Indexerstellungszeit.
    • 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 Abstimmungsparameter 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 werden für Ihre 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 1.048.576 festgelegt werden.

  • 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 verbessern, wenn die spaltenbasierte Engine aktiviert ist und Ihre Index- und Tabellendaten in die spaltenbasierte 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 optimieren.

Modi für vorhandene Indexe ändern

Wenn Sie einen ScaNN-Index im Modus AUTO erstellt haben und den Index manuell optimieren möchten, müssen Sie den Modus in MANUAL ändern.

So stellen Sie den Modus auf MANUAL um:

  1. Aktualisieren Sie den Index, um den Modus auf MANUAL festzulegen:

    ALTER INDEX INDEX_NAME SET (mode = 'MANUAL', num_leaves = NUM_LEAVES_VALUE);
    

    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.

    • NUM_LEAVES_VALUE: Die Anzahl der Partitionen, die auf diesen Index angewendet werden sollen. Kann auf einen beliebigen Wert zwischen 1 und 1.048.576 festgelegt werden.

    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 optimieren.

  2. Erstellen Sie Ihren Index neu, um die Parameter anzuwenden:

    REINDEX INDEX CONCURRENTLY INDEX_NAME;
    

So wechseln Sie in den Modus AUTO:

  1. Aktualisieren Sie den Index, um den Modus auf AUTO festzulegen:

    ALTER INDEX INDEX_NAME SET (mode = 'AUTO');
    
  2. Erstellen Sie Ihren Index neu, um die Parameter anzuwenden:

    REINDEX INDEX CONCURRENTLY INDEX_NAME;
    

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 Index mit zwei oder drei Ebenen erstellen. Weitere Informationen zum Optimieren von Parametern finden Sie unter ScaNN-Index optimieren.

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 1.048.576 festgelegt werden. Weitere Informationen dazu, wie Sie diesen Wert festlegen, finden Sie unter ScaNN-Index optimieren.

  • 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 verbessern, wenn die spaltenbasierte Engine aktiviert ist und Ihre Index- und Tabellendaten in die spaltenbasierte 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

Führen Sie die folgende DDL-Abfrage aus, um einen dreistufigen Baumindex mit dem ScaNN-Algorithmus für eine Spalte mit gespeicherten Vektoreinbettungen zu erstellen:

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 nach nächsten Nachbarn mit einem bestimmten Text erstellen.

Die Indexparameter müssen so festgelegt werden, dass ein gutes Gleichgewicht zwischen Abfragen pro Sekunde und Recall erreicht wird. Weitere Informationen zum Optimieren des ScaNN-Index finden Sie unter ScaNN-Index optimieren.

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.

Um eine konsistente Suche zu ermöglichen, sollten Sie die automatische Wartung aktivieren, wenn Sie einen ScaNN-Index erstellen. Weitere Informationen finden Sie unter Vektorindexe verwalten. Dieses Feature ist in der Vorschau verfügbar.

So rufen Sie den Indexierungsfortschritt auf:pg_stat_progress_create_index

SELECT * FROM pg_stat_progress_create_index;

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

Informationen zum Optimieren Ihres Index für ein ausgewogenes Verhältnis zwischen durchschnittlichem Recall und QPS finden Sie unter ScaNN-Index optimieren.

Indexe parallel erstellen

Damit Ihr Index schneller erstellt wird, kann AlloyDB je nach Dataset und Index automatisch mehrere parallele Worker starten.

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.

AlloyDB optimiert die Anzahl der parallelen Worker automatisch. Sie können sie jedoch 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:<->

    • Skalarprodukt:<#>

    • 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