Gestisci gli indici della Ricerca

Puoi creare un indice della Ricerca in BigQuery per eseguire ricerche testuali efficienti nei dati di stringa utilizzando la funzione SEARCH. La creazione di queste strutture di dati ausiliarie ti consente di ottimizzare in modo significativo le prestazioni complessive delle query per funzioni e operatori supportati.

Crea un indice di ricerca

Per creare un indice della Ricerca, utilizza l'istruzione DDL CREATE SEARCH INDEX. Per specificare i tipi di dati primitivi da indicizzare, consulta Crea un indice della Ricerca e specifica le colonne e i tipi di dati. Se non specifichi alcun tipo di dati, per impostazione predefinita BigQuery indicizza le colonne dei seguenti tipi che contengono dati STRING:

  • STRING
  • ARRAY<STRING>
  • STRUCT contenente almeno un campo nidificato di tipo STRING o ARRAY<STRING>
  • JSON

Quando crei un indice della Ricerca, puoi specificare il tipo di analizzatore di testo da utilizzare. L'analizzatore di testo controlla il modo in cui i dati vengono tokenizzati per l'indicizzazione e la ricerca. Il valore predefinito è LOG_ANALYZER. Questo analizzatore funziona bene per i log generati dalle macchine e ha regole speciali per i token che si trovano comunemente nei dati di osservabilità, come indirizzi IP o email. Utilizza NO_OP_ANALYZER quando hai dati pre-elaborati che vuoi far corrispondere esattamente. PATTERN_ANALYZER estrae i token dal testo utilizzando un'espressione regolare.

Crea un indice della Ricerca con l'analizzatore di testo predefinito

Nell'esempio seguente, viene creato un indice della Ricerca sulle colonne a e c di simple_table e utilizza l'analizzatore di testo LOG_ANALYZER per impostazione predefinita:

CREATE TABLE dataset.simple_table(a STRING, b INT64, c JSON);

CREATE SEARCH INDEX my_index
ON dataset.simple_table(a, c);

Crea un indice della Ricerca su tutte le colonne con l'analizzatore NO_OP_ANALYZER

Quando crei un indice della Ricerca su ALL COLUMNS, vengono indicizzati tutti i dati STRING o JSON nella tabella. Se la tabella non contiene dati di questo tipo, ad esempio se tutte le colonne contengono numeri interi, la creazione dell'indice non va a buon fine. Quando specifichi una colonna STRUCT da indicizzare, vengono indicizzati tutti i campi secondari nidificati.

Nell'esempio seguente, viene creato un indice della Ricerca su a, c.e e c.f.g, che utilizza l'analizzatore di testo NO_OP_ANALYZER:

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');

Poiché l'indice della Ricerca è stato creato su ALL COLUMNS, tutte le colonne aggiunte alla tabella vengono indicizzate automaticamente se contengono dati STRING.

Crea un indice della Ricerca e specifica le colonne e i tipi di dati

Quando crei un indice della Ricerca, puoi specificare i tipi di dati da utilizzare. I tipi di dati controllano i tipi di colonne e sottocampi delle colonne JSON e STRUCT per l'indicizzazione. Il tipo di dati predefinito per l'indicizzazione è STRING. Per creare un indice della Ricerca con più tipi di dati (ad esempio tipi numerici), utilizza l'istruzione CREATE SEARCH INDEX con l'opzione data_types inclusa.

Nell'esempio seguente, viene creato un indice della Ricerca sulle colonne a, b, c e d di una tabella denominata simple_table. I tipi di dati delle colonne supportati sono STRING, INT64 e 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']);

Crea un indice della Ricerca su tutte le colonne e specifica i tipi di dati

Quando crei un indice della Ricerca su ALL COLUMNS con l'opzione data_types specificata, viene indicizzata qualsiasi colonna che corrisponde a uno dei tipi di dati specificati. Per le colonne JSON e STRUCT, viene indicizzato qualsiasi sottocampo nidificato che corrisponde a uno dei tipi di dati specificati.

Nell'esempio seguente, viene creato un indice della Ricerca su ALL COLUMNS con i tipi di dati specificati. Le colonne a, b, c, d.e, d.f, d.g.h, d.g.i di una tabella denominata my_table sono indicizzate:

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']);

Poiché l'indice di ricerca è stato creato su ALL COLUMNS, tutte le colonne aggiunte alla tabella vengono indicizzate automaticamente se corrispondono a uno dei tipi di dati specificati.

Indice con granularità delle colonne

Quando crei un indice della Ricerca, puoi specificare la granularità delle colonne per una colonna indicizzata. La granularità delle colonne consente a BigQuery di ottimizzare alcuni tipi di query di ricerca archiviando informazioni aggiuntive sulle colonne nell'indice della Ricerca. Per impostare la granularità di una colonna indicizzata, utilizza l'opzione index_granularity in index_column_option_list quando esegui un'istruzione CREATE SEARCH INDEX.

Internamente, le tabelle BigQuery sono organizzate in file. Quando crei un indice, BigQuery crea una mappatura dai token ai file che li contengono. Quando esegui una query di ricerca, BigQuery analizza tutti i file che contengono i token. Questo potrebbe essere inefficiente se il token di ricerca appare raramente nella colonna in cui stai eseguendo la ricerca, ma è comune in un'altra colonna.

Ad esempio, supponiamo di avere la seguente tabella contenente offerte di lavoro:

CREATE TABLE my_dataset.job_postings (job_id INT64, company_name STRING, job_description STRING);

La parola skills probabilmente appare di frequente nella colonna job_description, ma raramente nella colonna company_name. Supponiamo di eseguire la seguente query:

SELECT * FROM my_dataset.job_postings WHERE SEARCH(company_name, 'skills');

Se hai creato un indice della Ricerca sulle colonne company_name e job_description senza specificare la granularità delle colonne, BigQuery scansionerà ogni file in cui la parola skills appare nella colonna job_description o company_name. Per migliorare le prestazioni di questa query, puoi impostare la granularità della colonna per company_name su COLUMN:

CREATE SEARCH INDEX my_index
ON my_dataset.job_postings (
  company_name OPTIONS(index_granularity = 'COLUMN'),
  job_description);

Ora, quando esegui la query, BigQuery analizza solo i file in cui la parola skills appare nella colonna company_name.

Per visualizzare informazioni sulle opzioni impostate sulle colonne di una tabella indicizzata, esegui una query sulla vista INFORMATION_SCHEMA.SEARCH_INDEX_COLUMN_OPTIONS.

Esistono limiti al numero di colonne che puoi indicizzare con la granularità delle colonne. Per saperne di più, consulta Quote e limiti.

Informazioni sull'aggiornamento dell'indice

Gli indici della Ricerca sono completamente gestiti da BigQuery e vengono aggiornati automaticamente quando la tabella cambia. Un aggiornamento completo dell'indice può verificarsi nei seguenti casi:

  • La scadenza della partizione viene aggiornata.
  • Una colonna indicizzata viene aggiornata a causa di una modifica dello schema della tabella.
  • L'indice non è aggiornato a causa della mancanza di slot di prenotazione BACKGROUND per gli aggiornamenti incrementali. Per evitare l'obsolescenza, puoi utilizzare la scalabilità automatica e monitorare il workload per determinare la dimensione ottimale della base di riferimento e della prenotazione massima.

Se i dati di una colonna indicizzata vengono aggiornati in ogni riga, ad esempio durante un'operazione di backfill, l'intero indice deve essere aggiornato, il che equivale a un aggiornamento completo. Ti consigliamo di eseguire i backfill lentamente, ad esempio partizione per partizione, per ridurre al minimo il potenziale impatto negativo.

Se apporti una modifica allo schema della tabella di base che impedisce l'indicizzazione di una colonna indicizzata in modo esplicito, l'indice viene disabilitato in modo permanente.

Se elimini l'unica colonna indicizzata di una tabella o rinomini la tabella stessa, l'indice della Ricerca viene eliminato automaticamente.

Gli indici della Ricerca sono progettati per tabelle di grandi dimensioni. Se crei un indice della Ricerca su una tabella di dimensioni inferiori a 10 GB, l'indice non viene compilato. Analogamente, se elimini i dati da una tabella indicizzata e le dimensioni della tabella scendono al di sotto di 10 GB, l'indice viene disattivato temporaneamente. In questo caso, le query di ricerca non utilizzano l'indice e il codice IndexUnusedReason è BASE_TABLE_TOO_SMALL. Questo avviene indipendentemente dal fatto che tu utilizzi o meno la tua prenotazione per i job di gestione degli indici. Quando le dimensioni di una tabella indicizzata superano i 10 GB, l'indice viene compilato automaticamente. Non ti verrà addebitato alcun costo per lo spazio di archiviazione finché l'indice della Ricerca non sarà compilato e attivo. Le query che utilizzano la funzione SEARCH restituiscono sempre risultati corretti, anche se alcuni dati non sono ancora indicizzati.

Aggiorna un indice della Ricerca

Per aggiornare la configurazione di un indice della Ricerca, utilizza l'istruzione DDL ALTER SEARCH INDEX. L'aggiornamento di un indice è particolarmente utile per le tabelle di grandi dimensioni perché consente di apportare modifiche incrementali, anziché eliminare e ricreare l'indice con una nuova configurazione.

Quando aggiorni un indice della Ricerca, BigQuery crea in modo asincrono un indice rivisto, riutilizzando il più possibile l'indice originale. Una volta che l'indice rivisto è sufficientemente popolato, diventa l'indice della tabella di base.

La tabella seguente può aiutarti a comprendere il costo delle diverse modifiche all'indice:

Azione Descrizione Costo
Elimina colonne. Aggiorna la configurazione istantaneamente. Se non specifichi REBUILD, si tratta di un'operazione solo sui metadati. Non vengono utilizzati slot aggiuntivi.
Aggiungi colonne o tipi di dati. Crea un indice rivisto elaborando i nuovi dati e riutilizzando i dati dell'indice esistente. Proporzionale alla quantità di nuovi dati da indicizzare.
Modifica la granularità dei token, combina più modifiche o libera spazio di archiviazione. Ricostruisce l'indice da zero. Questa operazione rimuove i dati dalle colonne o dai tipi di dati eliminati in precedenza. Questa pulizia riduce le dimensioni dell'indice, il che può potenzialmente migliorare le prestazioni delle query. Proporzionale alla dimensione totale dei dati indicizzati.

Puoi utilizzare il campo last_index_alteration_info nella vista INFORMATION_SCHEMA.SEARCH_INDEXES per monitorare la copertura dell'indice rivisto. Ad esempio, la query seguente mostra lo stato di modifica di tutti gli indici delle tabelle nel set di dati my_dataset nel progetto my_project. Se una modifica dell'indice è terminata, il valore di last_index_alteration_info è NULL.

SELECT
  table_name,
  index_name,
  last_index_alteration_info.status AS status,
  last_index_alteration_info.new_coverage_percentage AS coverage
FROM my_project.my_dataset.INFORMATION_SCHEMA.SEARCH_INDEXES

Il risultato è simile al seguente:

+------------+------------+-------------+----------+
| table_name | index_name | status      | coverage |
+------------+------------+-------------+----------+
| table1     | index_a    | IN_PROGRESS | 50       |
| table2     | index_b    | null        | null     |
+------------+------------+-------------+----------+

Per annullare una modifica dell'indice, utilizza la procedura di sistema BQ.CANCEL_INDEX_ALTERATION. Non puoi annullare una modifica dopo che è stata completata.

Ricevi informazioni sull'indice della Ricerca

Puoi verificare l'esistenza e l'idoneità di un indice della Ricerca eseguendo una query su INFORMATION_SCHEMA. Esistono tre visualizzazioni che contengono metadati sugli indici di ricerca.

INFORMATION_SCHEMA.SEARCH_INDEXES visualizza esempi

Questa sezione include query di esempio della vista INFORMATION_SCHEMA.SEARCH_INDEXES.

L'esempio seguente mostra tutti gli indici di ricerca attivi sulle tabelle nel set di dati my_dataset, che si trova nel progetto my_project. Include i nomi, le istruzioni DDL utilizzate per crearli, la percentuale di copertura e l'analizzatore di testo. Se una tabella di base indicizzata è inferiore a 10 GB, il relativo indice non viene compilato e in questo caso 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';

I risultati dovrebbero essere simili ai seguenti:

+-------------+-------------+--------------------------------------------------------------------------------------+---------------------+----------------+
| 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 visualizza esempi

Questa sezione include query di esempio della vista INFORMATION_SCHEMA.SEARCH_INDEX_COLUMNS.

L'esempio seguente crea un indice della Ricerca su tutte le colonne di my_table.

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);

La seguente query estrae informazioni sui campi indicizzati. index_field_path indica quale campo di una colonna è indicizzato. Questo valore è diverso da index_column_name solo nel caso di un STRUCT, in cui viene fornito il percorso completo del campo indicizzato. In questo esempio, la colonna c contiene un campo ARRAY<STRING> e e un altro STRUCT denominato f che contiene un campo STRING g, ognuno dei quali è indicizzato.

SELECT table_name, index_name, index_column_name, index_field_path
FROM my_project.dataset.INFORMATION_SCHEMA.SEARCH_INDEX_COLUMNS

Il risultato è simile al seguente:

+------------+------------+-------------------+------------------+
| 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            |
+------------+------------+-------------------+------------------+

La seguente query unisce la vista INFORMATION_SCHEMA.SEARCH_INDEX_COLUMNS alle viste INFORMATION_SCHEMA.SEARCH_INDEXES e INFORMATION_SCHEMA.COLUMNS per includere lo stato dell'indice della Ricerca e il tipo di dati di ogni colonna:

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;

Il risultato è simile al seguente:

+------------+------------+----------+------------+--------+-------------+------------+---------------------------------------------------------------+
| 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 visualizza esempi

Questa sezione include query di esempio della vista INFORMATION_SCHEMA.SEARCH_INDEXES_BY_ORGANIZATION.

Scopri se il consumo supera il limite in una determinata regione

L'esempio seguente illustra se la dimensione totale della tabella di base indicizzata in un'organizzazione, che utilizza slot condivisi all'interno della multi-regione degli Stati Uniti, supera i 100 TB:

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

Il risultato è simile al seguente:

+---------------------+
| total_logical_bytes |
+---------------------+
|     109951162777601 |
+---------------------+

Trova le dimensioni totali della tabella di base indicizzata per progetto in una regione

L'esempio seguente mostra la suddivisione di ogni progetto in una località multiregionale degli Stati Uniti con la dimensione totale delle tabelle di base indicizzate:

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

Il risultato è simile al seguente:

+---------------------+----------------------------+---------------------+
|     project_id      | use_background_reservation | total_logical_bytes |
+---------------------+----------------------------+---------------------+
| projecta            |     true                   |     971329178274633 |
+---------------------+----------------------------+---------------------+
| projectb            |     false                  |     834638211024843 |
+---------------------+----------------------------+---------------------+
| projectc            |     false                  |     562910385625126 |
+---------------------+----------------------------+---------------------+

Trova gli indici della Ricerca limitati

L'esempio seguente restituisce tutti gli indici della Ricerca con limitazioni all'interno dell'organizzazione e della regione:

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')

Il risultato è simile al seguente:

+--------------------+--------------------+---------------+----------------+
|     project_id     |    index_schema    |  table_name   |   index_name   |
+--------------------+--------------------+---------------+----------------+
|     projecta       |     dataset_us     |   table1      |    index1      |
|     projectb       |     dataset_us     |   table1      |    index1      |
+--------------------+--------------------+---------------+----------------+

Opzioni di gestione degli indici

Per creare gli indici e fare in modo che BigQuery li gestisca, hai due opzioni:

  • Utilizza il pool di slot condiviso predefinito: quando i dati che prevedi di indicizzare sono inferiori al limite per organizzazione, puoi utilizzare il pool di slot condiviso senza costi per la gestione dell'indice.
  • Utilizza la tua prenotazione: per ottenere un avanzamento dell'indicizzazione più prevedibile e coerente sui workload di produzione più grandi, puoi utilizzare le tue prenotazioni per la gestione degli indici.

Utilizza slot condivisi

Se non hai configurato il progetto per l'utilizzo di una prenotazione dedicata per l'indicizzazione, la gestione dell'indice viene gestita nel pool di slot condivisi senza costi, soggetto ai seguenti vincoli.

Se aggiungi dati a una tabella che fanno sì che la dimensione totale delle tabelle indicizzate superi il limite della tua organizzazione, BigQuery mette in pausa la gestione degli indici per quella tabella. In questo caso, il campo index_status nella vista INFORMATION_SCHEMA.SEARCH_INDEXES mostra PENDING DISABLEMENT e l'indice viene inserito in coda per l'eliminazione. Mentre l'indice è in attesa di essere disabilitato, viene comunque utilizzato nelle query e ti vengono addebitati i costi per l'archiviazione dell'indice. Dopo l'eliminazione dell'indice, il campo index_status mostra l'indice come TEMPORARILY DISABLED. In questo stato, le query non utilizzano l'indice e non ti vengono addebitati costi per l'archiviazione dell'indice. In questo caso, il codice IndexUnusedReason è BASE_TABLE_TOO_LARGE.

Se elimini i dati dalla tabella e la dimensione totale delle tabelle indicizzate scende al di sotto del limite per organizzazione, la gestione degli indici viene ripresa. Il campo index_status nella vista INFORMATION_SCHEMA.SEARCH_INDEXES è ACTIVE, le query possono utilizzare l'indice e ti viene addebitato il costo dello spazio di archiviazione dell'indice.

Puoi utilizzare la vista INFORMATION_SCHEMA.SEARCH_INDEXES_BY_ORGANIZATION per comprendere il consumo attuale rispetto al limite per organizzazione in una determinata regione, suddiviso per progetti e tabelle.

BigQuery non fornisce garanzie sulla capacità disponibile del pool condiviso o sul throughput di indicizzazione che vedi. Per le applicazioni di produzione, potresti voler utilizzare slot dedicati per l'elaborazione degli indici.

Utilizza la tua prenotazione

Anziché utilizzare il pool di slot condivisi predefinito, puoi facoltativamente designare la tua prenotazione per indicizzare le tabelle. L'utilizzo della tua prenotazione garantisce prestazioni prevedibili e coerenti dei job di gestione degli indici, come la creazione, l'aggiornamento e le ottimizzazioni in background.

  • Non esistono limiti di dimensione delle tabelle quando un job di indicizzazione viene eseguito nella tua prenotazione.
  • L'utilizzo della tua prenotazione ti offre flessibilità nella gestione degli indici. Se devi creare un indice molto grande o apportare un aggiornamento importante a una tabella indicizzata, puoi aggiungere temporaneamente altri slot all'assegnazione.

Per indicizzare le tabelle in un progetto con una prenotazione designata, crea una prenotazione nella regione in cui si trovano le tabelle. Poi, assegna il progetto alla prenotazione con job_type impostato su BACKGROUND, che condivide le risorse tra i job di ottimizzazione in background:

SQL

Utilizza l'istruzione DDL CREATE ASSIGNMENT.

  1. Nella console Google Cloud , vai alla pagina BigQuery.

    Vai a BigQuery

  2. Nell'editor di query, inserisci la seguente istruzione:

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

    Sostituisci quanto segue:

    • ADMIN_PROJECT_ID: l'ID progetto del progetto di amministrazione proprietario della risorsa di prenotazione
    • LOCATION: la località della prenotazione
    • RESERVATION_NAME: il nome della prenotazione
    • ASSIGNMENT_ID: l'ID dell'assegnazione

      L'ID deve essere univoco per il progetto e la località, iniziare e terminare con una lettera minuscola o un numero e contenere solo lettere minuscole, numeri e trattini.

    • PROJECT_ID: l'ID del progetto contenente le tabelle da indicizzare. Questo progetto è assegnato alla prenotazione.

  3. Fai clic su Esegui.

Per saperne di più su come eseguire le query, consulta Esegui una query interattiva.

bq

Utilizza il comando bq mk:

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

Sostituisci quanto segue:

  • ADMIN_PROJECT_ID: l'ID progetto del progetto di amministrazione proprietario della risorsa di prenotazione
  • LOCATION: la località della prenotazione
  • RESERVATION_NAME: il nome della prenotazione
  • PROJECT_ID: l'ID del progetto da assegnare a questa prenotazione

Visualizza i job di indicizzazione

Ogni volta che viene creato o aggiornato un indice su una singola tabella, viene creato un nuovo job di indicizzazione. Per visualizzare le informazioni sul job, esegui una query sulle viste INFORMATION_SCHEMA.JOBS*. Puoi filtrare i job di indicizzazione impostando job_type IS NULL AND SEARCH(job_id, '`search_index`') nella clausola WHERE della query. L'esempio seguente elenca i cinque job di indicizzazione più recenti nel progetto my_project:

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;

Scegli le dimensioni della prenotazione

Per scegliere il numero corretto di slot per la prenotazione, devi considerare quando vengono eseguiti i job di gestione degli indici, quanti slot utilizzano e l'utilizzo nel tempo. BigQuery attiva un job di gestione degli indici nelle seguenti situazioni:

  • Crei un indice su una tabella.
  • I dati vengono modificati in una tabella indicizzata.
  • Lo schema di una tabella cambia e questo influisce sulle colonne indicizzate.
  • I dati e i metadati dell'indice vengono ottimizzati o aggiornati periodicamente.

Il numero di slot necessari per un job di gestione degli indici su una tabella dipende dai seguenti fattori:

  • Le dimensioni della tabella
  • La frequenza di importazione dati nella tabella
  • La frequenza delle istruzioni DML applicate alla tabella
  • Il ritardo accettabile per la creazione e la manutenzione dell'indice
  • La complessità dell'indice, in genere determinata dagli attributi dei dati, come il numero di termini duplicati.
Stima iniziale

Le seguenti stime possono aiutarti ad approssimare il numero di slot richiesti dalla tua prenotazione. A causa della natura altamente variabile dei workload di indicizzazione, devi rivalutare i requisiti dopo aver iniziato l'indicizzazione dei dati.

  • Dati esistenti: con una prenotazione di 1000 slot, una tabella esistente in BigQuery può essere indicizzata a una velocità media massima di 4 GiB al secondo, ovvero circa 336 TiB al giorno.
  • Dati appena importati: l'indicizzazione è in genere più intensiva in termini di risorse sui dati appena importati, poiché la tabella e il relativo indice vengono sottoposti a diversi cicli di ottimizzazioni trasformative. In media, l'indicizzazione dei dati appena importati consuma tre volte più risorse rispetto all'indicizzazione iniziale di backfill degli stessi dati.
  • Dati modificati raramente: le tabelle indicizzate con poche o nessuna modifica dei dati richiedono molte meno risorse per la manutenzione continua dell'indice. Un punto di partenza consigliato è mantenere 1/5 degli slot richiesti per l'indicizzazione di backfill iniziale degli stessi dati e non meno di 250 slot.
  • L'avanzamento dell'indicizzazione aumenta in modo approssimativamente lineare con le dimensioni della prenotazione. Tuttavia, non consigliamo di utilizzare prenotazioni inferiori a 250 slot per l'indicizzazione, perché ciò potrebbe causare inefficienze che possono rallentare l'avanzamento dell'indicizzazione.
  • Queste stime possono cambiare in base alle funzionalità, alle ottimizzazioni e all'utilizzo effettivo.
  • Se le dimensioni totali delle tabelle della tua organizzazione superano il limite di indicizzazione della tua regione, devi mantenere una prenotazione diversa da zero assegnata per l'indicizzazione. In caso contrario, l'indicizzazione potrebbe tornare al livello predefinito, con conseguente eliminazione involontaria di tutti gli indici.
Monitora l'utilizzo e l'avanzamento

Il modo migliore per valutare il numero di slot necessari per eseguire in modo efficiente i job di gestione degli indici è monitorare l'utilizzo degli slot e regolare di conseguenza le dimensioni della prenotazione. La seguente query genera l'utilizzo giornaliero degli slot per i job di gestione degli indici. Nella regione us-west1 sono inclusi solo gli ultimi 30 giorni:

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;

Se non sono disponibili slot sufficienti per eseguire i job di gestione degli indici, un indice può non essere sincronizzato con la tabella e i job di indicizzazione potrebbero non riuscire. In questo caso, BigQuery ricrea l'indice da zero. Per evitare di avere un indice non sincronizzato, assicurati di avere slot sufficienti per supportare gli aggiornamenti dell'indice dall'importazione dati e dall'ottimizzazione. Per saperne di più sul monitoraggio dell'utilizzo degli slot, consulta Grafici delle risorse di amministrazione.

Best practice

  • Gli indici della Ricerca sono progettati per tabelle di grandi dimensioni. I miglioramenti delle prestazioni derivanti da un indice della Ricerca aumentano con le dimensioni della tabella.
  • Non indicizzare le colonne che contengono solo un numero molto ridotto di valori univoci.
  • Non indicizzare le colonne che non intendi utilizzare con la funzione SEARCH o con altre funzioni e operatori supportati.
  • Fai attenzione quando crei un indice della Ricerca su ALL COLUMNS. Ogni volta che aggiungi una colonna contenente dati STRING o JSON, questa viene indicizzata.
  • Per la gestione degli indici nelle applicazioni di produzione, devi utilizzare la tua prenotazione. Se scegli di utilizzare il pool di slot condivisi predefinito per i job di gestione degli indici, si applicano i limiti di dimensionamento per organizzazione.

Elimina un indice della Ricerca

Quando non hai più bisogno di un indice della Ricerca o vuoi modificare le colonne indicizzate in una tabella, puoi eliminare l'indice attualmente presente nella tabella. Utilizza l'istruzione DDL DROP SEARCH INDEX.

Se una tabella indicizzata viene eliminata, il relativo indice viene eliminato automaticamente.

Esempio:

DROP SEARCH INDEX my_index ON dataset.simple_table;

Passaggi successivi