Vektorindexe verwalten

In diesem Dokument wird beschrieben, wie Sie Vektorindexe erstellen und verwalten.

Ein Vektorindex ist eine Datenstruktur, die es der VECTOR_SEARCH-Funktion ermöglicht, eine effizientere Vektorsuche von Einbettungen durchzuführen. Wenn VECTOR_SEARCH einen Vektorindex verwenden kann, verwendet die Funktion die Suchmethode Annäherung an den nächsten Nachbarn, um die Suchleistung zu verbessern, mit dem Kompromiss von Recall reduzieren und so ungefähre Ergebnisse liefern.

Rollen und Berechtigungen

Zum Erstellen eines Vektorindex benötigen Sie die IAM-Berechtigung bigquery.tables.createIndex für die Tabelle, in der Sie den Index erstellen. Zum Löschen eines Vektorindex benötigen Sie die Berechtigung bigquery.tables.deleteIndex. Jede der folgenden vordefinierten IAM-Rollen enthält die Berechtigungen, die Sie benötigen, um mit Vektorindexen zu arbeiten:

  • BigQuery Dateninhaber (roles/bigquery.dataOwner)
  • BigQuery Datenmitbearbeiter (roles/bigquery.dataEditor)

Vektorindex erstellen

Verwenden Sie zum Erstellen eines Vektorindex die Datendefinitionssprachen-Anweisung (DDL) CREATE VECTOR INDEX:

  1. Rufen Sie die Seite BigQuery auf.

    BigQuery aufrufen

  2. Wählen Sie im Abfrageeditor einen Indextyp aus und führen Sie eine der folgenden SQL-Anweisungen aus:

    So erstellen Sie einen IVF-Vektorindex:

    CREATE [ OR REPLACE ] VECTOR INDEX [ IF NOT EXISTS ] INDEX_NAME
    ON DATASET_NAME.TABLE_NAME(COLUMN_NAME)
    STORING(STORED_COLUMN_NAME [, ...])
    OPTIONS(index_type = "IVF",
      distance_type = "DISTANCE_TYPE",
      ivf_options = '{"num_lists":NUM_LISTS}')

    So erstellen Sie einen TreeAH-Vektorindex:

    CREATE [ OR REPLACE ] VECTOR INDEX [ IF NOT EXISTS ] INDEX_NAME
    ON DATASET_NAME.TABLE_NAME(COLUMN_NAME)
    OPTIONS(index_type = "TREE_AH",
      distance_type = "DISTANCE_TYPE",
      tree_ah_options = '{"leaf_node_embedding_count":LEAF_NODE_EMBEDDING_COUNT,
        "normalization_type":"NORMALIZATION_TYPE"}')

    Weitere Informationen finden Sie unter Vector-Indextyp auswählen.

    Ersetzen Sie Folgendes:

    • INDEX_NAME: Der Name des zu erstellenden Vektorindexes. Da der Index immer im selben Projekt und Dataset wie die Basistabelle erstellt wird, müssen Sie Projekt und Dataset nicht im Namen angeben.
    • DATASET_NAME: der Name des Datasets, das die Tabelle enthält.
    • TABLE_NAME: der Name der Tabelle, die die Spalte mit den Daten für Einbettungen enthält.
    • COLUMN_NAME: Der Name einer Spalte, die die Daten der Einbettungen enthält. Die Spalte muss den Typ ARRAY<FLOAT64> haben. Die Spalte darf keine untergeordneten Felder haben. Alle Elemente im Array dürfen keine NULL-Elemente sein und alle Werte in der Spalte müssen dieselben Arraydimensionen haben.
    • STORED_COLUMN_NAME: Der Name einer Spalte oberster Ebene in der Tabelle, die im Vektorindex gespeichert werden soll. Der Spaltentyp darf nicht RANGE sein. Gespeicherte Spalten werden nicht verwendet, wenn die Tabelle eine Zugriffsrichtlinie auf Zeilenebene oder die Spalte ein Richtlinien-Tag hat. Informationen zum Aktivieren gespeicherter Spalten finden Sie unter Spalten speichern und vorfiltern.
    • DISTANCE_TYPE: Gibt den Standardabstandstyp an, der bei einer Vektorsuche mit diesem Index verwendet werden soll. Die unterstützten Werte sind EUCLIDEAN, COSINE und DOT_PRODUCT. Standardmäßig ist EUCLIDEAN ausgewählt.

      Für die Indexerstellung selbst wird immer die EUCLIDEAN-Entfernung für das Training verwendet. Die in der VECTOR_SEARCH-Funktion verwendete Entfernung kann jedoch abweichen.

      Wenn Sie einen Wert für das Argument distance_type der Funktion VECTOR_SEARCH angeben, wird dieser Wert anstelle des DISTANCE_TYPE-Werts verwendet.

    • NUM_LISTS: Ein INT64-Wert, der kleiner oder gleich 5.000 ist und angibt, wie viele Listen der IVF-Algorithmus erstellt. Der IVF-Algorithmus teilt den gesamten Datenraum in eine Anzahl von Listen auf, die NUM_LISTS entspricht. Datenpunkte, die näher beieinander liegen, werden mit höherer Wahrscheinlichkeit in dieselbe Liste aufgenommen. Wenn NUM_LISTS klein ist, haben Sie weniger Listen mit mehr Datenpunkten. Bei einem höheren Wert werden mehr Listen mit weniger Datenpunkten erstellt.

      Sie können NUM_LISTS in Kombination mit dem fraction_lists_to_search-Argument in der Funktion VECTOR_SEARCH verwenden, um eine effiziente Vektorsuche zu erstellen. Wenn Ihre Daten im Einbettungsraum in vielen kleinen Gruppen verteilt sind, geben Sie einen hohen Wert für NUM_LISTS an, um einen Index mit mehr Listen zu erstellen. Geben Sie einen niedrigeren Wert für fraction_lists_to_search an, um bei der Vektorsuche weniger Listen zu scannen. Verwenden Sie einen niedrigeren NUM_LISTS- und einen höheren fraction_lists_to_search-Wert wenn die Daten in weniger, größeren Gruppen verteilt sind. Wenn Sie einen hohen num_lists-Wert verwenden, kann das Erstellen des Vektorindexes länger dauern.

      Wenn Sie NUM_LISTS nicht angeben, berechnet BigQuery einen geeigneten Wert.

    • LEAF_NODE_EMBEDDING_COUNT: ein INT64-Wert, der größer oder gleich 500 ist und die ungefähre Anzahl der Vektoren in jedem Blattknoten des Baums angibt, den der TreeAH-Algorithmus erstellt. Der TreeAH-Algorithmus teilt den gesamten Datenraum in eine Reihe von Listen auf, wobei jede Liste etwa LEAF_NODE_EMBEDDING_COUNT Datenpunkte enthält. Je niedriger der Wert, desto mehr Listen mit weniger Datenpunkten werden erstellt. Je höher der Wert, desto weniger Listen mit mehr Datenpunkten werden erstellt. Der Standardwert ist 1.000.

    • NORMALIZATION_TYPE: Ein STRING-Wert Folgende Werte werden unterstützt: NONE or L2. Der Standardwert ist NONE. Die Normalisierung erfolgt vor jeder Verarbeitung, sowohl für die Daten der Basistabelle als auch für die Abfragedaten. Die Einbettungsspalte COLUMN_NAME in TABLE_NAME wird dabei nicht geändert. Je nach Datensatz, Einbettungsmodell und Distanztyp, der bei VECTOR_SEARCH verwendet wird, kann die Normalisierung der Einbettungen die Trefferquote verbessern.

Im folgenden Beispiel wird ein Vektorindex für die Spalte embedding von my_table erstellt:

CREATE TABLE my_dataset.my_table(embedding ARRAY<FLOAT64>);

CREATE VECTOR INDEX my_index ON my_dataset.my_table(embedding)
OPTIONS(index_type = 'IVF');

Im folgenden Beispiel wird ein Vektorindex für die Spalte embedding von my_table erstellt. Außerdem werden der zu verwendende Distanztyp und die IVF-Optionen angegeben:

CREATE TABLE my_dataset.my_table(embedding ARRAY<FLOAT64>);

CREATE VECTOR INDEX my_index ON my_dataset.my_table(embedding)
OPTIONS(index_type = 'IVF', distance_type = 'COSINE',
ivf_options = '{"num_lists": 2500}')

Im folgenden Beispiel wird ein Vektorindex für die Spalte embedding von my_table erstellt. Außerdem werden der zu verwendende Distanztyp und die TreeAH-Optionen angegeben:

CREATE TABLE my_dataset.my_table(id INT64, embedding ARRAY<FLOAT64>);

CREATE VECTOR INDEX my_index ON my_dataset.my_table(embedding)
OPTIONS (index_type = 'TREE_AH', distance_type = 'EUCLIDEAN',
tree_ah_options = '{"normalization_type": "L2"}');

Vektorindextyp auswählen

BigQuery bietet zwei Arten von Vektorindexen.

IVF-Index

IVF ist ein umgekehrter Dateiindex, bei dem die Vektordaten mit einem K-Means-Algorithmus geclustert und dann basierend auf diesen Clustern partitioniert werden. Wenn Sie die Funktion VECTOR_SEARCH verwenden, um in den Vektordaten zu suchen, können diese Partitionen verwendet werden, um die Menge der Daten zu reduzieren, die zum Ermitteln eines Ergebnisses gelesen werden müssen.

TreeAH-Index

TreeAH ist ein Vektorindex, der den ScaNN-Algorithmus von Google verwendet. Das funktioniert so:

  • Die Basistabelle wird in kleinere, überschaubarere Shards aufgeteilt.

  • Ein Clustermodell wird trainiert. Die Anzahl der Cluster wird aus der Option leaf_node_embedding_count in tree_ah_options abgeleitet.

  • Die Vektoren werden produktquantisiert und in den Indextabellen gespeichert.

  • Während VECTOR_SEARCH wird eine Kandidatenliste für jeden Abfragevektor effizient mithilfe von asymmetrischem Hashing berechnet, das für ungefähre Entfernungsberechnungen hardwareoptimiert ist. Diese Kandidaten werden dann mithilfe von genauen Einbettungen neu bewertet und neu sortiert.

Der TreeAH-Algorithmus ist für Batchabfragen optimiert, bei denen Hunderte oder mehr Abfragevektoren verarbeitet werden. Die Verwendung der Produktquantisierung kann die Latenz und die Kosten erheblich senken, möglicherweise um Größenordnungen im Vergleich zur IVF. Aufgrund des erhöhten Overheads ist der IVF-Algorithmus jedoch möglicherweise besser, wenn Sie eine kleinere Anzahl von Abfragevektoren haben.

Wir empfehlen den Indextyp „TreeAH“, wenn Ihr Anwendungsfall die folgenden Kriterien erfüllt:

  • Ihre Tabelle enthält maximal 200 Millionen Zeilen.

  • Sie führen häufig große Batchabfragen mit Hunderten oder mehr Abfragevektoren aus.

    Bei kleinen Batchabfragen greift VECTOR_SEARCH mit dem Indextyp „TreeAH“ möglicherweise auf die Brute-Force-Methode zurück. In diesem Fall wird ein Grund für den nicht verwendeten Vektorindex angegeben.

  • Für Ihren Workflow sind keine gespeicherten Spalten oder Vorabfilter erforderlich. In BigQuery werden Vorfilter, die mit einem TreeAH-Index verwendet werden, als Nachfilter behandelt.

Bei Fragen und Anliegen, insbesondere zu Skalierbarkeit, Limits und Leistung, können Sie sich unter bq-vector-search@google.com an uns wenden.

Spalten speichern und vorab filtern

Um die Effizienz Ihres Vektorindexes weiter zu verbessern, können Sie Spalten aus Ihrer Basistabelle angeben, die im Vektorindex gespeichert werden sollen. Mithilfe von gespeicherten Spalten lassen sich Abfragen, die die Funktion VECTOR_SEARCH aufrufen, auf folgende Weise optimieren:

  • Die Funktion VECTOR_SEARCH gibt eine Struktur namens base aus, die alle Spalten aus der Basistabelle enthält. Ohne gespeicherte Spalten ist ein potenziell teurer Join erforderlich, um die in base gespeicherten Spalten abzurufen. Wenn in Ihrer Abfrage nur gespeicherte Spalten aus base ausgewählt werden, optimiert BigQuery die Abfrage, um diesen Join zu entfernen.

  • Anstatt in einer ganzen Tabelle zu suchen, können Sie die VECTOR_SEARCH-Funktion in einer Abfrageanweisung aufrufen, die die Basistabelle mit einerWHERE-Klausel vorfiltert. Wenn Ihre Tabelle einen Index hat und Sie nur nach gespeicherten Spalten filtern, optimiert BigQuery die Abfrage, indem die Daten vor der Suche gefiltert und dann der Index für die Suche im kleineren Ergebnissatz verwendet wird. Wenn Sie nach Spalten filtern, die nicht gespeichert werden, wendet BigQuery den Filter nach der Suche in der Tabelle an. Diese Filter werden als Nachfilter bezeichnet.

    Die Nachfilterung ist weniger effizient und kann dazu führen, dass weniger als top_k Übereinstimmungen im Ergebnissatz vorhanden sind. In einigen Fällen kann die Vorabfilterung auch die Größe der Ergebnismenge verringern. Erhöhen Sie in diesem Fall den Wert von fraction_lists_to_search in Ihrem Aufruf auf VECTOR_SEARCH.

Wenn Sie Spalten speichern möchten, listen Sie sie in der STORING-Klausel der CREATE VECTOR INDEX-DDL-Anweisung auf. Wenn Sie Spalten speichern, erhöht sich die Größe des Vektorindexes. Daher sollten Sie nur die am häufigsten verwendeten oder gefilterten Spalten speichern.

Im folgenden Beispiel wird ein Vektorindex mit gespeicherten Spalten erstellt. Anschließend wird das Verhalten verschiedener Arten von Vektorsuchen erläutert:

-- Create a table that contains an embedding.
CREATE TABLE my_dataset.my_table(embedding ARRAY<FLOAT64>, type STRING, creation_time DATETIME, id INT64);

-- Create a query table that contains an embedding.
CREATE TABLE my_dataset.my_testdata(embedding ARRAY<FLOAT64>, test_id INT64);

-- Create a vector index with stored columns.
CREATE VECTOR INDEX my_index ON my_dataset.my_table(embedding)
STORING (type, creation_time)
OPTIONS (index_type = 'IVF');

-- Select only stored columns from a vector search to avoid an expensive join.
SELECT query, base.type, distance
FROM
  VECTOR_SEARCH(
    TABLE my_dataset.my_table,
    'embedding'
    TABLE my_dataset.my_testdata);

-- Pre-filter on a stored column. The index speeds up the query.
SELECT *
FROM
  VECTOR_SEARCH(
    (SELECT * FROM my_dataset.my_table WHERE type = 'animal'),
    'embedding',
    TABLE my_dataset.my_testdata);

-- Filter on a column that isn't stored. The index is used to search the
-- entire table, and then the results are post-filtered. You might see fewer
-- than 5 matches returned for some embeddings.
SELECT query.test_id, base.type, distance
FROM
  VECTOR_SEARCH(
    (SELECT * FROM my_dataset.my_table WHERE id = 123),
    'embedding',
    TABLE my_dataset.my_testdata,
    top_k => 5);

-- Use post-filters. The index is used, but the entire table is searched and
-- the post-filtering might reduce the number of results.
SELECT query.test_id, base.type, distance
FROM
  VECTOR_SEARCH(
    TABLE my_dataset.my_table,
    'embedding',
    TABLE my_dataset.my_testdata,
    top_k => 5)
WHERE base.type = 'animal';

-- Use pre-filters with brute force. The data is filtered and then searched
-- with brute force for exact results.
SELECT query.test_id, base.type, distance
FROM
  VECTOR_SEARCH(
    (SELECT * FROM my_dataset.my_table WHERE id = 123),
    'embedding',
    TABLE my_dataset.my_testdata,
    options => '{"use_brute_force":true}');

Beschränkungen

  • Sie können keine logischen Ansichten in Ihrem Vorabfilter verwenden.
  • Wenn Ihr Vorfilter eine Unterabfrage enthält, kann dies die Indexnutzung beeinträchtigen.
  • Wenn der Modus, der Typ oder das Schema einer Spalte in der Basistabelle geändert wird und es sich um eine im Vektorindex gespeicherte Spalte handelt, kann es eine Verzögerung geben, bis sich diese Änderung im Vektorindex widerspiegelt. Bis die Änderungen auf den Index angewendet wurden, werden in den Vektorsuchanfragen die geänderten gespeicherten Spalten aus der Basistabelle verwendet.
  • Wenn Sie eine Spalte vom Typ STRUCT aus der query-Ausgabe einer VECTOR_SEARCH-Abfrage für eine Tabelle mit einem Index mit gespeicherten Spalten auswählen, schlägt die gesamte Abfrage möglicherweise fehl.
  • Gespeicherte Spalten werden für TreeAH-Indexe nicht unterstützt.

Informationen zur Indexaktualisierung

Vektorindexe werden von BigQuery vollständig verwaltet und automatisch aktualisiert, wenn sich die indexierte Tabelle ändert. Wenn Sie die indexierte Spalte in einer Tabelle löschen oder die Tabelle selbst umbenennen, wird der Vektorindex automatisch gelöscht.

Wenn Sie einen Vektorindex für eine Tabelle erstellen, die kleiner als 10 MB ist, wird der Vektorindex nicht ausgefüllt. Dies gilt auch umgekehrt: Wenn Sie Daten aus einer indexierten Tabelle löschen und die Tabellengröße unter 10 MB liegt, wird der Vektorindex vorübergehend deaktiviert. In diesem Fall verwenden Vektorsuchanfragen nicht den Index und den indexUnusedReasons-Code im Abschnitt vectorSearchStatistics der Ressource Job ist BASE_TABLE_TOO_SMALL. Ohne den Index greift VECTOR_SEARCH automatisch auf Brute-Force-Angriffe zurück, um die nächsten Nachbarn von Einbettungen zu finden.

Abfragen, die die VECTOR_SEARCH-Funktion verwenden, geben immer korrekte Ergebnisse zurück, auch wenn ein Teil der Daten noch nicht indexiert ist.

Informationen zu Vektorindexen abrufen

Sie können das Vorhandensein und die Bereitschaft eines Vektorindex prüfen, indem Sie INFORMATION_SCHEMA abfragen. Die folgenden Ansichten enthalten Metadaten zu Vektorindexen:

  • Die Ansicht INFORMATION_SCHEMA.VECTOR_INDEXES enthält Informationen zu den Vektorindexen in einem Dataset.

    Nachdem die CREATE VECTOR INDEX-Anweisung abgeschlossen ist, muss der Index noch mit Daten gefüllt werden, bevor Sie ihn verwenden können. Anhand der Spalten last_refresh_time und coverage_percentage können Sie prüfen, ob ein Vektorindex bereit ist. Wenn der Vektorindex noch nicht bereit ist, können Sie die Funktion VECTOR_SEARCH trotzdem für eine Tabelle verwenden. Ohne Index ist die Ausführung jedoch möglicherweise langsamer.

  • Die Ansicht INFORMATION_SCHEMA.VECTOR_INDEX_COLUMNS enthält Informationen zu den vektorindexierten Spalten für alle Tabellen in einem Dataset.

  • Die Ansicht INFORMATION_SCHEMA.VECTOR_INDEX_OPTIONS enthält Informationen zu den Optionen, die von den Vektorindexen in einem Dataset verwendet werden.

Beispiele für Vektorindexe

Das folgende Beispiel zeigt alle aktiven Vektorindexe für Tabellen im Dataset my_dataset, das sich im Projekt my_project befindet. Darin enthalten sind die Namen, die zum Erstellen der Indexe verwendeten DDL-Anweisungen und der Deckungsprozentsatz. Ist eine indexierte Basistabelle kleiner als 10 MB, wird der Index nicht ausgefüllt. In diesem Fall ist der Wert coverage_percentage 0.

SELECT table_name, index_name, ddl, coverage_percentage
FROM my_project.my_dataset.INFORMATION_SCHEMA.VECTOR_INDEXES
WHERE index_status = 'ACTIVE';

Das Ergebnis sieht etwa so aus:

+------------+------------+-------------------------------------------------------------------------------------------------+---------------------+
| table_name | index_name | ddl                                                                                             | coverage_percentage |
+------------+------------+-------------------------------------------------------------------------------------------------+---------------------+
| table1     | indexa     | CREATE VECTOR INDEX `indexa` ON `my_project.my_dataset.table1`(embeddings)                      | 100                 |
|            |            | OPTIONS (distance_type = 'EUCLIDEAN', index_type = 'IVF', ivf_options = '{"num_lists": 100}')   |                     |
+------------+------------+-------------------------------------------------------------------------------------------------+---------------------+
| table2     | indexb     | CREATE VECTOR INDEX `indexb` ON `my_project.my_dataset.table2`(vectors)                         | 42                  |
|            |            | OPTIONS (distance_type = 'COSINE', index_type = 'IVF', ivf_options = '{"num_lists": 500}')      |                     |
+------------+------------+-------------------------------------------------------------------------------------------------+---------------------+
| table3     | indexc     | CREATE VECTOR INDEX `indexc` ON `my_project.my_dataset.table3`(vectors)                         | 98                  |
|            |            | OPTIONS (distance_type = 'DOT_PRODUCT', index_type = 'TREE_AH',                                 |                     |
|            |            |          tree_ah_options = '{"leaf_node_embedding_count": 1000, "normalization_type": "NONE"}') |                     |
+------------+------------+-------------------------------------------------------------------------------------------------+---------------------+

Beispiele für Vektorindexspalten

Die folgende Abfrage extrahiert Informationen zu Spalten mit Vektorindex:

SELECT table_name, index_name, index_column_name, index_field_path
FROM my_project.dataset.INFORMATION_SCHEMA.VECTOR_INDEX_COLUMNS;

Das Ergebnis sieht etwa so aus:

+------------+------------+-------------------+------------------+
| table_name | index_name | index_column_name | index_field_path |
+------------+------------+-------------------+------------------+
| table1     | indexa     | embeddings        | embeddings       |
| table2     | indexb     | vectors           | vectors          |
| table3     | indexc     | vectors           | vectors          |
+------------+------------+-------------------+------------------+

Beispiele für Vektorindexoptionen

Die folgende Abfrage extrahiert Informationen zu den Optionen für Vektorindexe:

SELECT table_name, index_name, option_name, option_type, option_value
FROM my_project.dataset.INFORMATION_SCHEMA.VECTOR_INDEX_OPTIONS;

Das Ergebnis sieht etwa so aus:

+------------+------------+------------------+------------------+-------------------------------------------------------------------+
| table_name | index_name | option_name      | option_type      | option_value                                                      |
+------------+------------+------------------+------------------+-------------------------------------------------------------------+
| table1     | indexa     | index_type       | STRING           | IVF                                                               |
| table1     | indexa     | distance_type    | STRING           | EUCLIDEAN                                                         |
| table1     | indexa     | ivf_options      | STRING           | {"num_lists": 100}                                                |
| table2     | indexb     | index_type       | STRING           | IVF                                                               |
| table2     | indexb     | distance_type    | STRING           | COSINE                                                            |
| table2     | indexb     | ivf_options      | STRING           | {"num_lists": 500}                                                |
| table3     | indexc     | index_type       | STRING           | TREE_AH                                                           |
| table3     | indexc     | distance_type    | STRING           | DOT_PRODUCT                                                       |
| table3     | indexc     | tree_ah_options  | STRING           | {"leaf_node_embedding_count": 1000, "normalization_type": "NONE"} |
+------------+------------+------------------+------------------+-------------------------------------------------------------------+

Vektorindexnutzung

Informationen zur Verwendung des Vektorindexes finden Sie in den Jobmetadaten des Jobs, für den die Vektorsuchabfrage ausgeführt wurde. Sie können Jobmetadaten aufrufen über die Google Cloud Console, das bq-Befehlszeilentool, die API oder die Clientbibliotheken.

In der Google Cloud Console finden Sie Informationen zur Verwendung des Vektorindexes in den Feldern Nutzungsmodus für Vektorindex und Nicht verwendete Gründe für Vektorindex.

Wenn Sie das bq-Tool oder die BigQuery API verwenden, finden Sie Informationen zur Nutzung von Vektorindexen im Abschnitt VectorSearchStatistics der Ressource Job.

Der Nutzungsmodus des Index gibt an, ob ein Vektorindex verwendet wurde. Dazu wird einer der folgenden Werte angegeben:

  • UNUSED: Es wurde kein Vektorindex verwendet.
  • PARTIALLY_USED: Für einige VECTOR_SEARCH-Funktionen in der Abfrage wurden Vektorindexe verwendet, für andere nicht.
  • FULLY_USED: Jede VECTOR_SEARCH-Funktion in der Abfrage hat einen Vektorindex verwendet.

Wenn der Wert für den Indexnutzungsmodus UNUSED oder PARTIALLY_USED ist, geben die Gründe für nicht verwendete Indexe an, warum Vektorindexe nicht in der Abfrage verwendet wurden.

Die folgenden von bq show --format=prettyjson -j my_job_id zurückgegebenen Ergebnisse zeigen beispielsweise, dass der Index nicht verwendet wurde, weil in der Funktion VECTOR_SEARCH die Option use_brute_force angegeben wurde:

"vectorSearchStatistics": {
  "indexUnusedReasons": [
    {
      "baseTable": {
        "datasetId": "my_dataset",
        "projectId": "my_project",
        "tableId": "my_table"
      },
      "code": "INDEX_SUPPRESSED_BY_FUNCTION_OPTION",
      "message": "No vector index was used for the base table `my_project:my_dataset.my_table` because use_brute_force option has been specified."
    }
  ],
  "indexUsageMode": "UNUSED"
}

Optionen für die Indexverwaltung

Sie haben zwei Möglichkeiten, Indexe zu erstellen und von BigQuery verwalten zu lassen:

  • Standardmäßigen freigegebenen Slot-Pool verwenden: Wenn die zu indexierenden Daten unter dem Limit pro Organisation liegen, können Sie den kostenlosen freigegebenen Slot-Pool für die Indexverwaltung verwenden.
  • Eigene Reservierung verwenden: Um einen vorhersehbaren und konsistenten Fortschritt bei der Indexierung für Ihre größeren Produktionsarbeitslasten zu erreichen, können Sie Ihre eigenen Reservierungen für die Indexverwaltung verwenden.

Freigegebene Slots verwenden

Wenn Sie Ihr Projekt nicht für die Verwendung einer dedizierten Reservierung für die Indexierung konfiguriert haben, wird die Indexverwaltung im kostenlosen, freigegebenen Slot-Pool durchgeführt, wobei die folgenden Einschränkungen gelten.

Wenn Sie einer Tabelle Daten hinzufügen, wodurch die Gesamtgröße der indexierten Tabelle das Limit Ihrer Organisation überschreitet, pausiert BigQuery die Indexverwaltung für alle indexierten Tabellen. In diesem Fall wird im Feld index_status in der Ansicht INFORMATION_SCHEMA.VECTOR_INDEXES PENDING DISABLEMENT angezeigt und der Index wird zum Löschen in die Warteschlange gestellt. Solange die Deaktivierung des Index aussteht, wird er noch in Anfragen verwendet und Indexspeicher wird Ihnen weiterhin in Rechnung gestellt. Nachdem ein Index gelöscht wurde, wird im Feld index_status der Index als TEMPORARILY DISABLED angezeigt. In diesem Zustand wird der Index nicht für Abfragen verwendet und Ihnen werden keine Kosten für den Indexspeicher berechnet. In diesem Fall lautet der IndexUnusedReason-Code BASE_TABLE_TOO_LARGE.

Wenn Sie Daten aus der Tabelle löschen und die Gesamtgröße der indexierten Tabelle unter das Limit pro Organisation fällt, wird die Indexverwaltung für alle indexierten Tabellen fortgesetzt. Das Feld index_status in der Ansicht INFORMATION_SCHEMA.VECTOR_INDEXES ist ACTIVE. Anfragen können den Index verwenden und Ihnen wird der Indexspeicher in Rechnung gestellt.

BigQuery gibt keine Garantien für die verfügbaren Kapazitäten des gemeinsamen Pools oder den angezeigten Durchsatz der Indexierung. Für Produktionsanwendungen kann die Verwendung dedizierter Slots für die Indexverarbeitung sinnvoll sein.

Eigene Reservierung verwenden

Anstatt den standardmäßigen freigegebenen Slot-Pool zu verwenden, können Sie optional eine eigene Reservierung festlegen, um Ihre Tabellen zu indexieren. Die Verwendung Ihrer eigenen Reservierung sorgt für eine vorhersagbare und konsistente Leistung von Indexverwaltungsjobs, z. B. Erstellungs-, Aktualisierungs- und Hintergrundoptimierungen.

  • Wenn ein Indexjob in Ihrer Reservierung ausgeführt wird, gibt es keine Größenbeschränkungen für Tabellen.
  • Mit der eigenen Reservierung können Sie Ihre Indexverwaltung flexibel verwalten. Wenn Sie einen sehr großen Index erstellen oder eine wichtige Aktualisierung einer indexierten Tabelle vornehmen müssen, können Sie der Zuweisung vorübergehend weitere Slots hinzufügen.

Um die Tabelle in einem Projekt mit einer bestimmten Reservierung zu indexieren, erstellen Sie eine Reservierung in der Region, in der sich Ihre Tabellen befinden. Weisen Sie der Reservierung dann das Projekt zu, wobei job_type auf BACKGROUND gesetzt ist:

SQL

Verwenden Sie die DDL-Anweisung CREATE ASSIGNMENT.

  1. Öffnen Sie in der Google Cloud Console die Seite BigQuery.

    BigQuery aufrufen

  2. Geben Sie im Abfrageeditor die folgende Anweisung ein:

    CREATE ASSIGNMENT
      `ADMIN_PROJECT_ID.region-LOCATION.RESERVATION_NAME.ASSIGNMENT_ID`
    OPTIONS (
      assignee = 'projects/PROJECT_ID',
      job_type = 'BACKGROUND');

    Ersetzen Sie Folgendes:

    • ADMIN_PROJECT_ID: die Projekt-ID des Administrationsprojekts, dem die Reservierungsressource gehört
    • LOCATION: der Standort der Reservierung
    • RESERVATION_NAME: der Name der Reservierung
    • ASSIGNMENT_ID: die ID der Zuweisung

      Die ID muss für das Projekt und den Standort eindeutig sein, mit einem Kleinbuchstaben oder einer Zahl beginnen und enden und darf nur Kleinbuchstaben, Zahlen und Bindestriche enthalten.

    • PROJECT_ID: die ID des Projekts, das die zu indexierenden Tabellen enthält. Dieses Projekt wird der Reservierung zugewiesen.

  3. Klicken Sie auf Ausführen.

Informationen zum Ausführen von Abfragen finden Sie unter Interaktive Abfrage ausführen.

bq

Führen Sie den Befehl bq mk aus:

bq mk \
    --project_id=ADMIN_PROJECT_ID \
    --location=LOCATION \
    --reservation_assignment \
    --reservation_id=RESERVATION_NAME \
    --assignee_id=PROJECT_ID \
    --job_type=BACKGROUND \
    --assignee_type=PROJECT

Ersetzen Sie Folgendes:

  • ADMIN_PROJECT_ID: die Projekt-ID des Administrationsprojekts, dem die Reservierungsressource gehört
  • LOCATION: der Standort der Reservierung
  • RESERVATION_NAME: der Name der Reservierung
  • PROJECT_ID: die ID des Projekts, das der Reservierung zugewiesen werden soll

Indexierungsjobs ansehen

Bei jeder Erstellung oder Aktualisierung eines Index für eine einzelne Tabelle wird ein neuer Indexierungsjob erstellt. Fragen Sie die Ansichten INFORMATION_SCHEMA.JOBS* ab, um Informationen zum Job anzuzeigen. Sie können nach Indexierungsjobs filtern, indem Sie job_type IS NULL AND SEARCH(job_id, '`search_index`') in der WHERE-Klausel Ihrer Abfrage festlegen. Im folgenden Beispiel werden die fünf neuesten Indexierungsjobs im Projekt my_project aufgelistet:

SELECT *
FROM
 region-us.INFORMATION_SCHEMA.JOBS
WHERE
  project_id  = 'my_project'
  AND job_type IS NULL
  AND SEARCH(job_id, '`search_index`')
ORDER BY
 creation_time DESC
LIMIT 5;

Reservierungsgröße auswählen

Wenn Sie die richtige Anzahl von Slots für Ihre Reservierung auswählen möchten, sollten Sie berücksichtigen, wann Jobs mit Indexverwaltung ausgeführt werden, wie viele Slots sie verwenden und wie Ihre Nutzung im Laufe der Zeit aussieht. BigQuery löst in den folgenden Situationen einen Indexverwaltungsjob aus:

  • Sie erstellen einen Index für eine Tabelle.
  • Daten werden in einer indexierten Tabelle geändert.
  • Das Schema einer Tabelle ändert sich, was sich darauf auswirkt, welche Spalten indexiert werden.
  • Indexdaten und Metadaten werden regelmäßig optimiert oder aktualisiert.

Die Anzahl der Slots, die Sie für einen Indexverwaltungsjob in einer Tabelle benötigen, hängt von den folgenden Faktoren ab:

  • Die Größe der Tabelle
  • Die Rate der Datenaufnahme in die Tabelle
  • Die Rate der DML-Anweisungen, die auf die Tabelle angewendet werden
  • Die akzeptable Verzögerung zum Erstellen und Verwalten des Index
  • Die Komplexität des Index; normalerweise bestimmt durch Attribute der Daten, z. B. die Anzahl doppelter Begriffe
Nutzung und Fortschritt im Blick behalten

Die beste Möglichkeit, die Anzahl der Slots zu ermitteln, die Sie für eine effiziente Ausführung Ihrer Indexverwaltungsjobs benötigen, besteht darin, die Slotauslastung zu beobachten und die Reservierungsgröße entsprechend anzupassen. Die folgende Abfrage gibt die tägliche Slotnutzung für Indexverwaltungsjobs an. Für die Region us-west1 werden nur die letzten 30 Tage berücksichtigt:

SELECT
  TIMESTAMP_TRUNC(job.creation_time, DAY) AS usage_date,
  -- Aggregate total_slots_ms used for index-management jobs in a day and divide
  -- by the number of milliseconds in a day. This value is most accurate for
  -- days with consistent slot usage.
  SAFE_DIVIDE(SUM(job.total_slot_ms), (1000 * 60 * 60 * 24)) AS average_daily_slot_usage
FROM
  `region-us-west1`.INFORMATION_SCHEMA.JOBS job
WHERE
  project_id = 'my_project'
  AND job_type IS NULL
  AND SEARCH(job_id, '`search_index`')
GROUP BY
  usage_date
ORDER BY
  usage_date DESC
limit 30;

Wenn nicht genügend Slots zum Ausführen von Indexverwaltungsjobs vorhanden sind, ist der Index möglicherweise nicht mehr mit seiner Tabelle synchron und Indexierungsjobs können fehlschlagen. In diesem Fall wird der Index in BigQuery neu erstellt. Achten Sie darauf, dass genügend Slots vorhanden sind, um Indexaktualisierungen aus der Datenaufnahme und -optimierung zu unterstützen, damit kein nicht synchronisierter Index. Weitere Informationen zum Überwachen der Slot-Nutzung finden Sie unter Diagramme zu administrativen Ressourcen.

Vektorindex löschen

Wenn Sie einen Vektorindex nicht mehr benötigen oder die in einer Tabelle indexierte Spalte ändern möchten, können Sie den Index für diese Tabelle mit der DDL-Anweisung DROP VECTOR INDEX löschen.

Beispiel:

DROP VECTOR INDEX my_index ON my_dataset.indexed_table;

Wenn eine indexierte Tabelle gelöscht wird, wird ihr Index automatisch gelöscht.

Nächste Schritte