Suchindexe verwalten
Ein Suchindex ist eine Datenstruktur, die eine sehr effiziente Suche mit der Funktion SEARCH
ermöglicht. Mit einem Suchindex lassen sich auch einige Abfragen optimieren, bei denen unterstützte Funktionen und Operatoren verwendet werden.
Ähnlich wie der Index, den Sie in einem Buch finden würden, agiert ein Suchindex für eine Spalte mit Stringdaten wie eine Hilfstabelle, die zwei Spalten enthält: eine für bestimmte Wörter und eine weitere für die Stelle, an der die Wörter in den Daten vorkommen.
Suchindex erstellen
Verwenden Sie zum Erstellen eines Suchindex die DDL-Anweisung CREATE SEARCH INDEX
. Informationen zum Angeben von zu indexierenden primitiven Datentypen finden Sie unter Suchindex erstellen und Spalten und Datentypen angeben. Wenn Sie keine Datentypen angeben, indexiert BigQuery standardmäßig Spalten der folgenden Typen, die STRING
-Daten enthalten:
STRING
ARRAY<STRING>
STRUCT
, das mindestens ein verschachteltes Feld vom TypSTRING
oderARRAY<STRING>
enthältJSON
Wenn Sie einen Suchindex erstellen, können Sie den zu verwendenden Textanalysator angeben. Der Textanalysator steuert, wie Daten für die Indexierung und Suche tokenisiert werden. Der Standardwert ist LOG_ANALYZER
. Dieser Analysetool funktioniert gut mit maschinengenerierten Logs. Er hat spezielle Regeln für Tokens, die häufig in Beobachtbarkeitsdaten wie IP-Adressen oder E-Mails gefunden werden. Verwenden Sie NO_OP_ANALYZER
, wenn vorverarbeitete Daten, die Sie genau abgleichen möchten, bereits vorhanden sind.
PATTERN_ANALYZER
extrahiert Tokens aus einem Text mithilfe eines regulären Ausdrucks.
Suchindex mit dem Standardtextanalysator erstellen
Im folgenden Beispiel wird ein Suchindex für die Spalten a
und c
von simple_table
erstellt und standardmäßig der Textanalysator LOG_ANALYZER
verwendet:
CREATE TABLE dataset.simple_table(a STRING, b INT64, c JSON); CREATE SEARCH INDEX my_index ON dataset.simple_table(a, c);
Suchindex für alle Spalten mit dem Analysator NO_OP_ANALYZER
erstellen
Wenn Sie einen Suchindex für ALL COLUMNS
erstellen, werden alle STRING
- oder JSON
-Daten in der Tabelle indexiert. Wenn die Tabelle keine solchen Daten enthält, z. B. wenn alle Spalten Ganzzahlen enthalten, schlägt die Indexerstellung fehl. Wenn Sie eine zu indexierende STRUCT
-Spalte angeben, werden alle verschachtelten Unterfelder indexiert.
Im folgenden Beispiel wird ein Suchindex für a
, c.e
und c.f.g
erstellt und der Textanalysator NO_OP_ANALYZER
verwendet:
CREATE TABLE dataset.my_table( a STRING, b INT64, c STRUCT <d INT64, e ARRAY<STRING>, f STRUCT<g STRING, h INT64>>) AS SELECT 'hello' AS a, 10 AS b, (20, ['x', 'y'], ('z', 30)) AS c; CREATE SEARCH INDEX my_index ON dataset.my_table(ALL COLUMNS) OPTIONS (analyzer = 'NO_OP_ANALYZER');
Da der Suchindex für ALL COLUMNS
erstellt wurde, werden alle der Tabelle hinzugefügten Spalten automatisch indexiert, wenn sie STRING
-Daten enthalten.
Suchindex erstellen und Spalten und Datentypen angeben
Wenn Sie einen Suchindex erstellen, können Sie die zu verwendenden Datentypen angeben. Datentypen steuern die Typen von Spalten und Unterfeldern von JSON
- und STRUCT
-Spalten für die Indexierung. Der Standarddatentyp für die Indexierung ist STRING
. Wenn Sie einen Suchindex mit mehreren Datentypen erstellen möchten (z. B. numerische Typen), verwenden Sie die Anweisung CREATE SEARCH INDEX
mit der Option data_types
.
Im folgenden Beispiel wird ein Suchindex für die Spalten a
, b
, c
und d
einer Tabelle mit dem Namen simple_table
erstellt. Unterstützte Spaltendatentypen sind STRING
, INT64
und TIMESTAMP
.
CREATE TABLE dataset.simple_table(a STRING, b INT64, c JSON, d TIMESTAMP); CREATE SEARCH INDEX my_index ON dataset.simple_table(a, b, c, d) OPTIONS ( data_types = ['STRING', 'INT64', 'TIMESTAMP']);
Suchindex für alle Spalten erstellen und Datentypen angeben
Wenn Sie einen Suchindex für ALL COLUMNS
erstellen und die Option data_types
angeben, wird jede Spalte indexiert, die einem der angegebenen Datentypen entspricht.
Bei JSON
- und STRUCT
-Spalten wird jedes verschachtelte Unterfeld, das einem der angegebenen Datentypen entspricht, indexiert.
Im folgenden Beispiel wird ein Suchindex für ALL COLUMNS
mit angegebenen Datentypen erstellt. Die Spalten a
, b
, c
, d.e
, d.f
, d.g.h
, d.g.i
einer Tabelle mit dem Namen my_table
werden indexiert:
CREATE TABLE dataset.my_table( a STRING, b INT64, c TIMESTAMP, d STRUCT <e INT64, f ARRAY<STRING>, g STRUCT<h STRING, i INT64>>) AS ( SELECT 'hello' AS a, 10 AS b, TIMESTAMP('2008-12-25 15:30:00 UTC') AS c, (20, ['x', 'y'], ('z', 30)) AS d; ) CREATE SEARCH INDEX my_index ON dataset.my_table(ALL COLUMNS) OPTIONS ( data_types = ['STRING', 'INT64', 'TIMESTAMP']);
Da der Suchindex für ALL COLUMNS
erstellt wurde, werden alle der Tabelle hinzugefügten Spalten automatisch indexiert, wenn sie mit einem der angegebenen Datentypen übereinstimmen.
Index mit Spaltengranularität
Wenn Sie einen Suchindex erstellen, können Sie die Spaltengranularität für eine indexierte Spalte angeben. Mit der Spaltengranularität kann BigQuery bestimmte Arten von Suchanfragen optimieren, indem zusätzliche Spalteninformationen in Ihrem Suchindex gespeichert werden. Wenn Sie den Spaltendetaillierungsgrad für eine indexierte Spalte festlegen möchten, verwenden Sie die Option index_granularity
in der index_column_option_list
, wenn Sie eine CREATE SEARCH INDEX
-Anweisung ausführen.
Intern sind BigQuery-Tabellen in Dateien organisiert. Wenn Sie einen Index erstellen, erstellt BigQuery eine Zuordnung von Tokens zu den Dateien, die diese Tokens enthalten. Wenn Sie eine Suchanfrage ausführen, werden in BigQuery alle Dateien gescannt, die die Tokens enthalten. Das kann ineffizient sein, wenn Ihr Suchtoken selten in der Spalte vorkommt, in der Sie suchen, aber häufig in einer anderen Spalte.
Angenommen, Sie haben die folgende Tabelle mit Stellenanzeigen:
CREATE TABLE my_dataset.job_postings (job_id INT64, company_name STRING, job_description STRING);
Das Wort Fähigkeiten kommt wahrscheinlich häufig in der Spalte job_description
, aber selten in der Spalte company_name
vor. Angenommen, Sie führen die folgende Abfrage aus:
SELECT * FROM my_dataset.job_postings WHERE SEARCH(company_name, 'skills');
Wenn Sie einen Suchindex für die Spalten company_name
und job_description
erstellt haben, ohne die Spaltengranularität anzugeben, würde BigQuery jede Datei scannen, in der das Wort skills in der Spalte job_description
oder company_name
vorkommt.
Um die Leistung dieser Abfrage zu verbessern, können Sie die Spaltengranularität für company_name
auf COLUMN
festlegen:
CREATE SEARCH INDEX my_index
ON my_dataset.job_postings (
company_name OPTIONS(index_granularity = 'COLUMN'),
job_description);
Wenn Sie die Abfrage jetzt ausführen, werden in BigQuery nur die Dateien gescannt, in denen das Wort skills in der Spalte company_name
vorkommt.
Wenn Sie Informationen dazu sehen möchten, welche Optionen für die Spalten einer indexierten Tabelle festgelegt sind, fragen Sie die INFORMATION_SCHEMA.SEARCH_INDEX_COLUMN_OPTIONS
-Ansicht ab.
Es gibt Einschränkungen hinsichtlich der Anzahl der Spalten, die Sie mit Spaltengranularität indexieren können. Weitere Informationen finden Sie unter Kontingente und Limits.
Informationen zur Indexaktualisierung
Suchindexe werden von BigQuery vollständig verwaltet und automatisch aktualisiert, wenn sich die Tabelle ändert. Eine vollständige Aktualisierung des Index kann in den folgenden Fällen erfolgen:
- Der Partitionsablauf wird aktualisiert.
- Eine indexierte Spalte wird aufgrund einer Änderung des Tabellenschemas aktualisiert.
- Der Index ist veraltet, da es nicht genügend
BACKGROUND
-Reservierungsslots für inkrementelle Aktualisierungen gibt. Um veraltete Daten zu vermeiden, können Sie Autoscaling verwenden und die Arbeitslast überwachen, um die beste Referenz- und maximale Reservierungsgröße zu ermitteln.
Wenn die Daten einer indexierten Spalte in jeder Zeile aktualisiert werden, z. B. bei einer Backfill-Operation, muss der gesamte Index aktualisiert werden, was einem vollständigen Aktualisieren entspricht. Wir empfehlen, Backfills langsam durchzuführen, z. B. partitioniert, um potenzielle negative Auswirkungen zu minimieren.
Wenn Sie das Schema der Basistabelle so ändern, dass eine explizit indexierte Spalte nicht mehr indexiert werden kann, wird der Index dauerhaft deaktiviert.
Wenn Sie die einzige indexierte Spalte in einer Tabelle löschen oder die Tabelle selbst umbenennen, wird der Suchindex automatisch gelöscht.
Suchindexe sind für große Tabellen konzipiert. Wenn Sie einen Suchindex für eine Tabelle erstellen, die kleiner als 10 GB ist, wird der Index nicht ausgefüllt. Dies gilt auch umgekehrt: Wenn Sie Daten aus einer indexierten Tabelle löschen und die Tabellengröße unter 10 GB liegt, wird der Index vorübergehend deaktiviert. In diesem Fall verwenden Suchanfragen nicht den Index und der IndexUnusedReason
-Code ist BASE_TABLE_TOO_SMALL
. Dies geschieht unabhängig davon, ob Sie Ihre eigene Reservierung für Ihre Indexverwaltungsjobs verwenden. Wenn die Größe einer indexierten Tabelle 10 GB überschreitet, wird der Index automatisch ausgefüllt. Der Speicher wird Ihnen erst in Rechnung gestellt, wenn der Suchindex ausgefüllt und aktiv ist. Abfragen, die die SEARCH
-Funktion verwenden, geben immer korrekte Ergebnisse zurück, auch wenn einige Daten noch nicht indexiert sind.
Informationen zu Suchindexen abrufen
Sie können das Vorhandensein und die Bereitschaft eines Suchindex prüfen, indem Sie INFORMATION_SCHEMA
abfragen. Es gibt drei Ansichten, die Metadaten zu Suchindexen enthalten.
- Die Ansicht
INFORMATION_SCHEMA.SEARCH_INDEXES
enthält Informationen zu jedem Suchindex, der für ein Dataset erstellt wurde. - Die Ansicht
INFORMATION_SCHEMA.SEARCH_INDEX_COLUMNS
enthält Informationen dazu, welche Spalten jeder Tabelle im Dataset indexiert sind. - Die Ansicht
INFORMATION_SCHEMA.SEARCH_INDEXES_BY_ORGANIZATION
enthält Informationen zu Suchindexen für die gesamte Organisation, die dem aktuellen Projekt zugeordnet ist.
INFORMATION_SCHEMA.SEARCH_INDEXES
Beispiele ansehen
Dieser Abschnitt enthält Beispielabfragen für die Ansicht INFORMATION_SCHEMA.SEARCH_INDEXES
.
Das folgende Beispiel zeigt alle aktiven Suchindexe für Tabellen im Dataset my_dataset
, das sich im Projekt my_project
befindet. Sie enthält die Namen, die zum Erstellen verwendeten DDL-Anweisungen, den Deckungsprozentsatz und den Textanalysator. Ist eine indexierte Basistabelle kleiner als 10 GB, wird der Index nicht ausgefüllt. In diesem Fall ist coverage_percentage
0.
SELECT table_name, index_name, ddl, coverage_percentage, analyzer
FROM my_project.my_dataset.INFORMATION_SCHEMA.SEARCH_INDEXES
WHERE index_status = 'ACTIVE';
Die Ergebnisse sollten so aussehen:
+-------------+-------------+--------------------------------------------------------------------------------------+---------------------+----------------+ | table_name | index_name | ddl | coverage_percentage | analyzer | +-------------+-------------+--------------------------------------------------------------------------------------+---------------------+----------------+ | small_table | names_index | CREATE SEARCH INDEX `names_index` ON `my_project.my_dataset.small_table`(names) | 0 | NO_OP_ANALYZER | | large_table | logs_index | CREATE SEARCH INDEX `logs_index` ON `my_project.my_dataset.large_table`(ALL COLUMNS) | 100 | LOG_ANALYZER | +-------------+-------------+--------------------------------------------------------------------------------------+---------------------+----------------+
INFORMATION_SCHEMA.SEARCH_INDEX_COLUMNS
Beispiele ansehen
Dieser Abschnitt enthält Beispielabfragen für die Ansicht INFORMATION_SCHEMA.SEARCH_INDEX_COLUMNS
.
Im folgenden Beispiel wird ein Suchindex für alle Spalten von my_table
erstellt.
CREATE TABLE dataset.my_table( a STRING, b INT64, c STRUCT <d INT64, e ARRAY<STRING>, f STRUCT<g STRING, h INT64>>) AS SELECT 'hello' AS a, 10 AS b, (20, ['x', 'y'], ('z', 30)) AS c; CREATE SEARCH INDEX my_index ON dataset.my_table(ALL COLUMNS);
Die folgende Abfrage extrahiert Informationen darüber, welche Felder indexiert wurden.
index_field_path
gibt an, welches Feld einer Spalte indexiert ist. Dies unterscheidet sich von index_column_name
nur im Fall eines STRUCT
, bei dem der vollständige Pfad zum indexierten Feld angegeben wird. In diesem Beispiel enthält die Spalte c
das ARRAY<STRING>
-Feld e
und ein weiteres STRUCT
namens f
, das das STRING
-Feld g
enthält, und beide sind indexiert.
SELECT table_name, index_name, index_column_name, index_field_path
FROM my_project.dataset.INFORMATION_SCHEMA.SEARCH_INDEX_COLUMNS
Das Ergebnis sieht etwa so aus:
+------------+------------+-------------------+------------------+ | table_name | index_name | index_column_name | index_field_path | +------------+------------+-------------------+------------------+ | my_table | my_index | a | a | | my_table | my_index | c | c.e | | my_table | my_index | c | c.f.g | +------------+------------+-------------------+------------------+
Die folgende Abfrage verknüpft die Ansicht INFORMATION_SCHEMA.SEARCH_INDEX_COUMNS
mit den Ansichten INFORMATION_SCHEMA.SEARCH_INDEXES
und INFORMATION_SCHEMA.COLUMNS
, um den Suchindexstatus und den Datentyp jeder Spalte einzubeziehen:
SELECT index_columns_view.index_catalog AS project_name, index_columns_view.index_SCHEMA AS dataset_name, indexes_view.TABLE_NAME AS table_name, indexes_view.INDEX_NAME AS index_name, indexes_view.INDEX_STATUS AS status, index_columns_view.INDEX_COLUMN_NAME AS column_name, index_columns_view.INDEX_FIELD_PATH AS field_path, columns_view.DATA_TYPE AS data_type FROM mydataset.INFORMATION_SCHEMA.SEARCH_INDEXES indexes_view INNER JOIN mydataset.INFORMATION_SCHEMA.SEARCH_INDEX_COLUMNS index_columns_view ON indexes_view.TABLE_NAME = index_columns_view.TABLE_NAME AND indexes_view.INDEX_NAME = index_columns_view.INDEX_NAME LEFT OUTER JOIN mydataset.INFORMATION_SCHEMA.COLUMNS columns_view ON indexes_view.INDEX_CATALOG = columns_view.TABLE_CATALOG AND indexes_view.INDEX_SCHEMA = columns_view.TABLE_SCHEMA AND index_columns_view.TABLE_NAME = columns_view.TABLE_NAME AND index_columns_view.INDEX_COLUMN_NAME = columns_view.COLUMN_NAME ORDER BY project_name, dataset_name, table_name, column_name;
Das Ergebnis sieht etwa so aus:
+------------+------------+----------+------------+--------+-------------+------------+---------------------------------------------------------------+ | project | dataset | table | index_name | status | column_name | field_path | data_type | +------------+------------+----------+------------+--------+-------------+------------+---------------------------------------------------------------+ | my_project | my_dataset | my_table | my_index | ACTIVE | a | a | STRING | | my_project | my_dataset | my_table | my_index | ACTIVE | c | c.e | STRUCT<d INT64, e ARRAY<STRING>, f STRUCT<g STRING, h INT64>> | | my_project | my_dataset | my_table | my_index | ACTIVE | c | c.f.g | STRUCT<d INT64, e ARRAY<STRING>, f STRUCT<g STRING, h INT64>> | +------------+------------+----------+------------+--------+-------------+------------+---------------------------------------------------------------+
INFORMATION_SCHEMA.SEARCH_INDEXES_BY_ORGANIZATION
Beispiele ansehen
Dieser Abschnitt enthält Beispielabfragen für die Ansicht INFORMATION_SCHEMA.SEARCH_INDEXES_BY_ORGANIZATION
.
Herausfinden, ob die Nutzung das Limit in einer bestimmten Region überschreitet
Im folgenden Beispiel wird veranschaulicht, ob die Gesamtgröße der indexierten Basistabellen in einer Organisation, die freigegebene Slots in der US-Mehrfachregion nutzt, 100 TB überschreitet:
WITH indexed_base_table_size AS ( SELECT SUM(base_table.total_logical_bytes) AS total_logical_bytes FROM `region-us`.INFORMATION_SCHEMA.SEARCH_INDEXES_BY_ORGANIZATION AS search_index JOIN `region-us`.INFORMATION_SCHEMA.TABLE_STORAGE_BY_ORGANIZATION AS base_table ON (search_index.table_name = base_table.table_name AND search_index.project_id = base_table.project_id AND search_index.index_schema = base_table.table_schema) WHERE TRUE -- Excludes search indexes that are permanently disabled. AND search_index.index_status != 'PERMANENTLY DISABLED' -- Excludes BASE_TABLE_TOO_SMALL search indexes whose base table size is -- less than 10 GB. These tables don't count toward the limit. AND search_index.index_status_details.throttle_status != 'BASE_TABLE_TOO_SMALL' -- Excludes search indexes whose project has BACKGROUND reservation purchased -- for search indexes. AND search_index.use_background_reservation = false -- Outputs the total indexed base table size if it exceeds 100 TB, -- otherwise, doesn't return any output. ) SELECT * FROM indexed_base_table_size WHERE total_logical_bytes >= 109951162777600 -- 100 TB
Das Ergebnis sieht etwa so aus:
+---------------------+ | total_logical_bytes | +---------------------+ | 109951162777601 | +---------------------+
Gesamtgröße der indexierten Basistabellen nach Projekten in einer Region ermitteln
Im folgenden Beispiel wird die Aufschlüsselung für jedes Projekt in einer US-Multiregion mit der Gesamtgröße der indexierten Basistabellen dargestellt:
SELECT search_index.project_id, search_index.use_background_reservation, SUM(base_table.total_logical_bytes) AS total_logical_bytes FROM `region-us`.INFORMATION_SCHEMA.SEARCH_INDEXES_BY_ORGANIZATION AS search_index JOIN `region-us`.INFORMATION_SCHEMA.TABLE_STORAGE_BY_ORGANIZATION AS base_table ON (search_index.table_name = base_table.table_name AND search_index.project_id = base_table.project_id AND search_index.index_schema = base_table.table_schema) WHERE TRUE -- Excludes search indexes that are permanently disabled. AND search_index.index_status != 'PERMANENTLY DISABLED' -- Excludes BASE_TABLE_TOO_SMALL search indexes whose base table size is -- less than 10 GB. These tables don't count toward limit. AND search_index.index_status_details.throttle_status != 'BASE_TABLE_TOO_SMALL' GROUP BY search_index.project_id, search_index.use_background_reservation
Das Ergebnis sieht etwa so aus:
+---------------------+----------------------------+---------------------+ | project_id | use_background_reservation | total_logical_bytes | +---------------------+----------------------------+---------------------+ | projecta | true | 971329178274633 | +---------------------+----------------------------+---------------------+ | projectb | false | 834638211024843 | +---------------------+----------------------------+---------------------+ | projectc | false | 562910385625126 | +---------------------+----------------------------+---------------------+
Gedrosselte Suchindexe finden
Im folgenden Beispiel werden alle Suchindexe zurückgegeben, die in der Organisation und Region gedrosselt werden:
SELECT project_id, index_schema, table_name, index_name FROM `region-us`.INFORMATION_SCHEMA.SEARCH_INDEXES_BY_ORGANIZATION WHERE -- Excludes search indexes that are permanently disabled. index_status != 'PERMANENTLY DISABLED' AND index_status_details.throttle_status IN ('ORGANIZATION_LIMIT_EXCEEDED', 'BASE_TABLE_TOO_LARGE')
Das Ergebnis sieht etwa so aus:
+--------------------+--------------------+---------------+----------------+ | project_id | index_schema | table_name | index_name | +--------------------+--------------------+---------------+----------------+ | projecta | dataset_us | table1 | index1 | | projectb | dataset_us | table1 | index1 | +--------------------+--------------------+---------------+----------------+
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.SEARCH_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 er im Feld index_status
als TEMPORARILY DISABLED
angezeigt. In diesem Zustand wird der Index nicht für Anfragen verwendet und Ihnen wird der Indexspeicher nicht in Rechnung gestellt. 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.SEARCH_INDEXES
ist ACTIVE
. Anfragen können den Index verwenden und Ihnen wird der Indexspeicher in Rechnung gestellt.
Mit der Ansicht INFORMATION_SCHEMA.SEARCH_INDEXES_BY_ORGANIZATION
können Sie Ihren aktuellen Verbrauch im Hinblick auf das organisationsbezogene Limit in einer bestimmten Region aufgeschlüsselt nach Projekten und Tabellen nachvollziehen.
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 Datenerfassung in der 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
Erste Schätzung
Die folgenden Schätzungen können Ihnen helfen, die Anzahl der Slots zu ermitteln, die für Ihre Reservierung erforderlich sind. Da die Indexierung von Arbeitslasten sehr variabel ist, sollten Sie Ihre Anforderungen nach der Indexierung von Daten noch einmal neu bewerten.
- Vorhandene Daten: Mit einer Reservierung mit 1.000 Slots kann eine vorhandene Tabelle in BigQuery mit einer durchschnittlichen Rate von bis zu 4 GiB pro Sekunde indexiert werden. Dies entspricht ungefähr 336 TiB pro Tag.
- Neu aufgenommene Daten: Die Indexierung ist in der Regel ressourcenintensiver für neu aufgenommene Daten, da die Tabelle und ihr Index mehrere Transformationsoptimierungen durchlaufen. Im Durchschnitt verbrauchen neu aufgenommene Daten bei der Indexierung im Vergleich zur ersten Backfill-Indexierung derselben Daten dreimal so viele Ressourcen.
- Selten geänderte Daten: Für indexierte Tabellen mit wenig oder keinen Datenänderungen sind wesentlich weniger Ressourcen für die fortlaufende Indexwartung erforderlich. Ein empfohlener Ausgangspunkt ist die Beizubehalten von 1/5 der Slots, die für die anfängliche Backfill-Indexierung derselben Daten erforderlich sind, und nicht weniger als 250 Slots.
- Der Indexierungsfortschritt skaliert in etwa linear mit der Reservierungsgröße. Wir empfehlen jedoch nicht, Reservierungen mit weniger als 250 Slots für die Indexierung zu verwenden, da dies zu Ineffizienzen führen kann, die den Indexierungsfortschritt verlangsamen können.
- Diese Schätzungen können sich ändern, wenn sich Funktionen, Optimierungen und Ihre tatsächliche Nutzung ändern.
- Wenn die gesamte Tabellengröße der Organisation das Indexierungslimit Ihrer Region überschreitet, sollten Sie für die Indexierung eine Reservierung ungleich null beibehalten. Andernfalls kann die Indexierung auf die Standardstufe zurückfallen, was zu einem unbeabsichtigten Löschen aller Indexe führt.
Nutzung und Fortschritt im Blick behalten
Die beste Methode, um die Anzahl der Slots zu ermitteln, die Sie zum effizienten Ausführen Ihrer Jobs mit Indexverwaltung benötigen, besteht darin, die Slotnutzung zu beobachten und die Reservierungsgröße entsprechend anzupassen. Die folgende Abfrage gibt die tägliche Slot-Nutzung für Indexverwaltungsjobs zurück. In der Region us-west1
sind nur die letzten 30 Tage enthalten:
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 von Grund auf 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 zur Überwachung der Slot-Nutzung finden Sie unter Diagramme zu administrativen Ressourcen.
Best Practices
- Suchindexe sind für große Tabellen konzipiert. Die Leistung eines Suchindex nimmt mit der Größe der Tabelle zu.
- Indexieren Sie keine Spalten, die nur eine sehr kleine Anzahl eindeutiger Werte enthalten.
- Indexieren Sie keine Spalten, die Sie nie mit der Funktion
SEARCH
oder einer der anderen unterstützten Funktionen und Operatoren verwenden möchten. - Seien Sie vorsichtig, wenn Sie einen Suchindex für
ALL COLUMNS
erstellen. Jedes Mal, wenn Sie eine Spalte mitSTRING
- oderJSON
-Daten hinzufügen, wird sie indexiert. - Für die Indexverwaltung in Produktionsanwendungen sollten Sie Ihre eigene Reservierung verwenden. Wenn Sie für Ihre Indexverwaltungsjobs den standardmäßigen gemeinsamen Slot-Pool verwenden, gelten die Größen-Limits für die einzelnen Organisationen.
Suchindex löschen
Wenn Sie einen Suchindex nicht mehr benötigen oder die in einer Tabelle indexierten Spalten ändern möchten, können Sie den Index löschen, der aktuell für diese Tabelle gilt. Verwenden Sie die DDL-Anweisung DROP SEARCH INDEX
.
Wenn eine indexierte Tabelle gelöscht wird, wird ihr Index automatisch gelöscht.
Beispiel:
DROP SEARCH INDEX my_index ON dataset.simple_table;
Nächste Schritte
- Eine Übersicht über Anwendungsfälle für den Suchindex, die Preise, die erforderlichen Berechtigungen und Einschränkungen finden Sie unter Einführung in die Suche in BigQuery.
- Informationen zur effizienten Suche in indexierten Spalten finden Sie unter Mit einem Index suchen.