Vektorindexe verwalten
In diesem Dokument wird beschrieben, wie Sie Vektorindexe erstellen und verwalten, um Ihre Vektorsuchen zu beschleunigen.
Ein Vektorindex ist eine Datenstruktur, die die Ausführung der Funktion VECTOR_SEARCH
effizienter macht, insbesondere bei großen Datenmengen.
Bei Verwendung eines Index verwendet VECTOR_SEARCH
ANN-Algorithmen (Approximate Nearest Neighbor), um die Abfragelatenz und die Rechenkosten zu reduzieren. ANNs führen zwar zu einer gewissen Näherung, d. h. die Trefferquote ist möglicherweise nicht 100%, die Leistungsverbesserungen bieten jedoch in der Regel einen Vorteil für die meisten Anwendungen.
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
)
Vektorindextyp auswählen
BigQuery bietet zwei Arten von Vektorindexen: IVF und TreeAH. Sie unterstützen jeweils unterschiedliche Anwendungsfälle. BigQuery unterstützt Batchverarbeitungen für die Vektorsuche, indem mehrere Zeilen der Eingabedaten in der Funktion VECTOR_SEARCH
verarbeitet werden.
Für kleine Abfrage-Batches werden IVF-Indexe bevorzugt. Für große Abfrage-Batches werden TreeAH-Indexe bevorzugt, die mit dem ScaNN-Algorithmus von Google erstellt werden.
IVF-Index
IVF ist ein umgekehrter Dateiindex, bei dem die Vektordaten mit einem K-Means-Algorithmus geclustert und dann anhand dieser Cluster partitioniert werden. Mit der Funktion VECTOR_SEARCH
können diese Partitionen verwendet werden, um die Menge der zu lesenden Daten zu reduzieren, um ein Ergebnis zu ermitteln.
TreeAH-Index
Der Indextyp „TreeAH“ ist nach der Kombination aus einer baumartigen Struktur und der Verwendung von asymmetrischem Hashing (AH) benannt, einer Quantisierungstechnik aus dem zugrunde liegenden ScaNN-Algorithmus. Ein TreeAH-Index 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
im Argumenttree_ah_options
der AnweisungCREATE VECTOR INDEX
abgeleitet. - Die Vektoren werden mithilfe der Produktquantisierung komprimiert, wodurch die Speichernutzung reduziert wird. Die komprimierten Vektoren werden dann anstelle der ursprünglichen Vektoren in den Indextabellen gespeichert, wodurch die Größe der Vektorindizes reduziert wird.
- Wenn die
VECTOR_SEARCH
-Funktion ausgeführt wird, 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 mit dem Indextyp „TreeAH“ wechselt VECTOR_SEARCH
möglicherweise zur Brute-Force-Suche.
In diesem Fall wird der Grund für die Nichtverwendung des Vektorindexes mithilfe des IndexUnusedReason angegeben.
IVF-Vektorindex erstellen
Verwenden Sie zum Erstellen eines IVF-Vektorindexes die Datendefinitionssprachen-Anweisung (DDL) CREATE VECTOR INDEX
:
Rufen Sie die Seite BigQuery auf.
Führen Sie im Abfrageeditor folgende SQL-Anweisung 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}')
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 TypARRAY<FLOAT64>
haben. Die Spalte darf keine untergeordneten Felder haben. Alle Elemente im Array dürfen keineNULL
-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 nichtRANGE
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 sindEUCLIDEAN
,COSINE
undDOT_PRODUCT
. Standardmäßig istEUCLIDEAN
ausgewählt.Für die Indexerstellung selbst wird immer die
EUCLIDEAN
-Entfernung für das Training verwendet. Die in derVECTOR_SEARCH
-Funktion verwendete Entfernung kann jedoch abweichen.Wenn Sie einen Wert für das Argument
distance_type
der FunktionVECTOR_SEARCH
angeben, wird dieser Wert anstelle desDISTANCE_TYPE
-Werts verwendet.NUM_LISTS
: einINT64
-Wert, der die Anzahl der Listen angibt, in die der IVF-Index Ihre Vektordaten clustert und dann partitioniert. Dieser Wert darf maximal 5.000 sein. Während der Indexierung werden Vektoren der Liste zugewiesen, die dem nächsten Clustermittelpunkt entspricht. Wenn Sie dieses Argument weglassen, ermittelt BigQuery anhand Ihrer Datenmerkmale einen Standardwert. Der Standardwert funktioniert für die meisten Anwendungsfälle gut.Mit
NUM_LISTS
wird die Detaillierung der Abfrageoptimierung gesteuert. Je höher der Wert, desto mehr Listen werden erstellt. Sie können die Optionfraction_lists_to_search
der FunktionVECTOR_SEARCH
so festlegen, dass ein kleinerer Prozentsatz des Index gescannt wird. Beispiel: 1% von 100 Listen werden gescannt, anstatt 10% von 10 Listen. Dies ermöglicht eine genauere Steuerung der Suchgeschwindigkeit und des Abrufs, erhöht aber die Indexierungskosten geringfügig. Legen Sie diesen Argumentwert fest, je nachdem, wie genau Sie den Abfrageumfang anpassen möchten.
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}')
TreeAH-Vektorindex erstellen
Verwenden Sie zum Erstellen eines TreeAH-Vektorindexes die Datendefinitionssprachen-Anweisung (DDL) CREATE VECTOR INDEX
:
Rufen Sie die Seite BigQuery auf.
Führen Sie im Abfrageeditor folgende SQL-Anweisung aus:
CREATE [ OR REPLACE ] VECTOR INDEX [ IF NOT EXISTS ] INDEX_NAME ON DATASET_NAME.TABLE_NAME(COLUMN_NAME) STORING(STORED_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"}')
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 TypARRAY<FLOAT64>
haben. Die Spalte darf keine untergeordneten Felder haben. Alle Elemente im Array dürfen keineNULL
-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 nichtRANGE
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
: ein optionales Argument, das den Standardtyp für die Entfernung angibt, der bei einer Vektorsuche mit diesem Index verwendet werden soll. Die unterstützten Werte sindEUCLIDEAN
,COSINE
undDOT_PRODUCT
. Standardmäßig istEUCLIDEAN
ausgewählt.Für die Indexerstellung selbst wird immer die
EUCLIDEAN
-Entfernung für das Training verwendet. Die in derVECTOR_SEARCH
-Funktion verwendete Entfernung kann jedoch abweichen.Wenn Sie einen Wert für das Argument
distance_type
der FunktionVECTOR_SEARCH
angeben, wird dieser Wert anstelle desDISTANCE_TYPE
-Werts verwendet.LEAF_NODE_EMBEDDING_COUNT
: einINT64
-Wert, der größer oder gleich 500 ist und die ungefähre Anzahl der Vektoren in jedem Blattknoten des Baums angibt, der vom TreeAH-Algorithmus erstellt wird. Der TreeAH-Algorithmus teilt den gesamten Datenraum in eine Reihe von Listen auf, wobei jede Liste etwaLEAF_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, was für die meisten Datensätze geeignet ist.NORMALIZATION_TYPE
: EinSTRING
-Wert Folgende Werte werden unterstützt:NONE
oderL2
. Der Standardwert istNONE
. Die Normalisierung erfolgt vor jeder Verarbeitung, sowohl für die Daten der Basistabelle als auch für die Abfragedaten. Die EinbettungsspalteCOLUMN_NAME
inTABLE_NAME
wird dabei nicht geändert. Je nach Datensatz, Einbettungsmodell und Distanztyp, der beiVECTOR_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. 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"}');
Spalten speichern und vorfiltern
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, in denen die Funktion VECTOR_SEARCH
aufgerufen wird, auf folgende Weise optimieren:
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 Funktion
VECTOR_SEARCH
gibt eine Struktur namensbase
aus, die alle Spalten aus der Basistabelle enthält. Ohne gespeicherte Spalten ist ein potenziell teurer Join erforderlich, um die inbase
gespeicherten Spalten abzurufen. Wenn Sie einen IVF-Index verwenden und in Ihrer Abfrage nur gespeicherte Spalten ausbase
ausgewählt werden, optimiert BigQuery die Abfrage, um diese Join-Operation zu entfernen. Bei TreeAH-Indexen wird die Verknüpfung mit der Basistabelle nicht entfernt. Gespeicherte Spalten in TreeAH-Indexen werden nur für das Vorfiltern verwendet.
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 und dann eine Vektorsuchabfrage ausgeführt, bei der nur gespeicherte Spalten ausgewählt werden:
-- 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);
Vor- und Nachfilter
Bei BigQuery-VECTOR_SEARCH
-Vorgängen dienen sowohl Vorab- als auch Nachfilterung dazu, die Suchergebnisse zu verfeinern, indem Bedingungen auf der Grundlage von Metadatenspalten angewendet werden, die mit den Vektor-Embeddings verknüpft sind. Es ist wichtig, ihre Unterschiede, Implementierung und Auswirkungen zu verstehen, um die Abfrageleistung, die Kosten und die Genauigkeit zu optimieren.
Vor- und Nachfilterung sind so definiert:
- Vorabfilterung:Filterbedingungen werden angewendet, bevor bei der Suche nach dem ungefähren Nächsten (ANN) Distanzberechnungen für Kandidatenvektoren durchgeführt werden. Dadurch wird der Pool der Vektoren, die bei der Suche berücksichtigt werden, eingegrenzt. Daher führt die Vorabfilterung häufig zu kürzeren Abfragezeiten und geringeren Rechenkosten, da bei der ANN-Suche weniger potenzielle Kandidaten ausgewertet werden.
- Nachfilterung:Filterbedingungen werden angewendet, nachdem die ersten
top_k
Nähesten Nachbarn durch die ANN-Suche ermittelt wurden. Dadurch wird der endgültige Ergebnissatz anhand der angegebenen Kriterien verfeinert.
Die Platzierung der WHERE
-Klausel bestimmt, ob ein Filter als Vor- oder Nachfilter dient.
Wenn Sie einen Vorfilter erstellen möchten, muss die WHERE
-Klausel der Abfrage auf das Basistabellenargument der VECTOR_SEARCH
-Funktion angewendet werden.
Das Prädikat muss auf eine gespeicherte Spalte angewendet werden, andernfalls wird es zu einem Postfilter.
Das folgende Beispiel zeigt, wie ein Vorfilter erstellt wird:
-- 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 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}');
Wenn Sie einen Nachfilter erstellen möchten, muss die WHERE
-Klausel der Abfrage außerhalb der VECTOR_SEARCH
-Funktion angewendet werden, damit die von der Suche zurückgegebenen Ergebnisse gefiltert werden.
Das folgende Beispiel zeigt, wie ein Post-Filter erstellt wird:
-- 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'; SELECT base.id, distance FROM VECTOR_SEARCH( TABLE mydataset.base_table, 'embedding', (SELECT embedding FROM mydataset.query_table), top_k => 10 ) WHERE type = 'document' AND year > 2022
Wenn Sie die Nachfilterung verwenden oder die von Ihnen angegebenen Filter für die Basistabelle auf nicht gespeicherte Spalten verweisen und daher als Nachfilter fungieren, enthält der endgültige Ergebnissatz möglicherweise weniger als top_k
Zeilen, möglicherweise sogar keine, wenn das Prädikat selektiv ist. Wenn Sie nach dem Filtern eine bestimmte Anzahl von Ergebnissen benötigen, können Sie einen größeren top_k
-Wert angeben oder den fraction_lists_to_search
-Wert im VECTOR_SEARCH
-Aufruf erhöhen.
In einigen Fällen, insbesondere wenn der Vorfilter sehr selektiv ist, kann die Vorfilterung auch die Größe der Ergebnismenge verringern. Erhöhen Sie in diesem Fall den Wert fraction_lists_to_search
im VECTOR_SEARCH
-Aufruf.
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 derquery
-Ausgabe einerVECTOR_SEARCH
-Abfrage in einer Tabelle mit einem Index mit gespeicherten Spalten auswählen, schlägt die gesamte Abfrage möglicherweise fehl.
Wann werden Daten indexiert?
Vektorindexe werden von BigQuery vollständig verwaltet und automatisch aktualisiert, wenn sich die indexierte Tabelle ändert.
Die Indexierung erfolgt asynchron. Zwischen dem Hinzufügen neuer Zeilen zur Basistabelle und dem Einbeziehen der neuen Zeilen in den Index gibt es eine Verzögerung. Die Funktion VECTOR_SEARCH
berücksichtigt jedoch alle Zeilen und übersieht keine nicht indexierten Zeilen. Die Funktion sucht mithilfe des Index nach indexierten Einträgen und verwendet die Brute-Force-Suche für die Einträge, die noch nicht indexiert sind.
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.
Wenn Sie die indexierte Spalte in einer Tabelle löschen oder die Tabelle selbst umbenennen, wird der Vektorindex automatisch gelöscht.
Status von Vektorindexen im Blick behalten
Sie können den Zustand Ihrer Vektorindizes überwachen, indem Sie INFORMATION_SCHEMA
-Ansichten 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 Spaltenlast_refresh_time
undcoverage_percentage
können Sie prüfen, ob ein Vektorindex bereit ist. Wenn der Vektorindex noch nicht bereit ist, können Sie die FunktionVECTOR_SEARCH
trotzdem für eine Tabelle verwenden. Ohne Index wird sie jedoch möglicherweise langsamer ausgeführt.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"} | +------------+------------+------------------+------------------+-------------------------------------------------------------------+
Verwendung des Vektorindexes prüfen
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 BigQuery API oder die Clientbibliotheken.
In der Google Cloud Console finden Sie Informationen zur Verwendung des Vektorindexes in den Feldern Nutzungsmodus für Vektorindex und Gründe für nicht verwendeten 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 einigeVECTOR_SEARCH
-Funktionen in der Abfrage wurden Vektorindexe verwendet, für andere nicht.FULLY_USED
: JedeVECTOR_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
.
Rufen Sie in der Google Cloud Console die Seite BigQuery auf.
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örtLOCATION
: der Standort der ReservierungRESERVATION_NAME
: der Name der ReservierungASSIGNMENT_ID
: die ID der ZuweisungDie 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.
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örtLOCATION
: der Standort der ReservierungRESERVATION_NAME
: der Name der ReservierungPROJECT_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
- Eine Übersicht über Anwendungsfälle, Preise und Einschränkungen für den Vektorindex finden Sie unter Einführung in die Vektorsuche.
- Informationen zum Ausführen einer Vektorsuche mit der Funktion
VECTOR_SEARCH
- Weitere Informationen zur
CREATE VECTOR INDEX
-Anweisung - Sehen Sie sich die Anleitung zum Suchen nach Einbettungen mit der Vektorsuche an.