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 Typ STRING oder ARRAY<STRING> enthält
  • JSON

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.

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.

  1. Rufen Sie in der Google Cloud Console die Seite BigQuery auf.

    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 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 mit STRING- oder JSON-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