Faça a gestão dos índices de pesquisa

Um índice de pesquisa é uma estrutura de dados concebida para permitir uma pesquisa muito eficiente com a função SEARCH. Um índice de pesquisa também pode otimizar algumas consultas que usam funções e operadores suportados.

Tal como o índice que encontra no final de um livro, um índice de pesquisa para uma coluna de dados de string funciona como uma tabela auxiliar que tem uma coluna para palavras únicas e outra para a localização dessas palavras nos dados.

Crie um índice de pesquisa

Para criar um índice de pesquisa, use a declaração DDL CREATE SEARCH INDEX. Para especificar tipos de dados primitivos a indexar, consulte o artigo Crie um índice de pesquisa e especifique as colunas e os tipos de dados. Se não especificar tipos de dados, o BigQuery indexa por predefinição as colunas dos seguintes tipos que contêm dados STRING:

  • STRING
  • ARRAY<STRING>
  • STRUCT que contenha, pelo menos, um campo aninhado do tipo STRING ou ARRAY<STRING>
  • JSON

Quando cria um índice de pesquisa, pode especificar o tipo de analisador de texto a usar. O analisador de texto controla a forma como os dados são tokenizados para indexação e pesquisa. A predefinição é LOG_ANALYZER. Este analisador funciona bem para registos gerados por máquinas e tem regras especiais sobre tokens encontrados frequentemente em dados de observabilidade, como endereços IP ou emails. Use a opção NO_OP_ANALYZER quando tiver dados pré-processados que quer fazer corresponder exatamente. PATTERN_ANALYZER extrai tokens do texto através de uma expressão regular.

Crie um índice de pesquisa com o analisador de texto predefinido

No exemplo seguinte, é criado um índice de pesquisa nas colunas a e c de simple_table e usa o analisador de texto LOG_ANALYZER por predefinição:

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

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

Crie um índice de pesquisa em todas as colunas com o analisador NO_OP_ANALYZER

Quando cria um índice de pesquisa em ALL COLUMNS, todos os dados STRING ou JSON na tabela são indexados. Se a tabela não contiver esses dados, por exemplo, se todas as colunas contiverem números inteiros, a criação do índice falha. Quando especifica uma coluna STRUCT para ser indexada, todos os subcampos aninhados são indexados.

No exemplo seguinte, é criado um índice de pesquisa em a, c.e e c.f.g, e usa o analisador de texto 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');

Uma vez que o índice de pesquisa foi criado a ALL COLUMNS, todas as colunas adicionadas à tabela são indexadas automaticamente se contiverem dados STRING.

Crie um índice de pesquisa e especifique as colunas e os tipos de dados

Quando cria um índice de pesquisa, pode especificar os tipos de dados a usar. Os tipos de dados controlam os tipos de colunas e subcampos das colunas JSON e STRUCT para indexação. O tipo de dados predefinido para a indexação é STRING. Para criar um índice de pesquisa com mais tipos de dados (por exemplo, tipos numéricos), use a declaração CREATE SEARCH INDEX com a opção data_types incluída.

No exemplo seguinte, é criado um índice de pesquisa nas colunas a, b, c e d de uma tabela denominada simple_table. Os tipos de dados de colunas suportados são 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']);

Crie um índice de pesquisa em todas as colunas e especifique os tipos de dados

Quando cria um índice de pesquisa no ALL COLUMNS com a opção data_types especificada, qualquer coluna que corresponda a um dos tipos de dados especificados é indexada. Para as colunas JSON e STRUCT, qualquer subcampo aninhado que corresponda a um dos tipos de dados especificados é indexado.

No exemplo seguinte, é criado um índice de pesquisa em ALL COLUMNS com os tipos de dados especificados. As colunas a, b, c, d.e, d.f, d.g.h, d.g.i de uma tabela denominada my_table são indexadas:

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

Uma vez que o índice de pesquisa foi criado a ALL COLUMNS, todas as colunas adicionadas à tabela são automaticamente indexadas se corresponderem a algum dos tipos de dados especificados.

Indexe com granularidade de coluna

Quando cria um índice de pesquisa, pode especificar a granularidade das colunas para uma coluna indexada. A granularidade das colunas permite ao BigQuery otimizar determinados tipos de consultas de pesquisa armazenando informações adicionais das colunas no seu índice de pesquisa. Para definir a granularidade da coluna para uma coluna indexada, use a opção index_granularity no index_column_option_list quando executar uma declaração CREATE SEARCH INDEX.

Internamente, as tabelas do BigQuery estão organizadas em ficheiros. Quando cria um índice, o BigQuery cria um mapeamento de tokens para os ficheiros que contêm esses tokens. Quando executa uma consulta de pesquisa, o BigQuery analisa todos os ficheiros que contêm os tokens. Isto pode ser ineficiente se o seu token de pesquisa aparecer raramente na coluna que está a pesquisar, mas for comum numa coluna diferente.

Por exemplo, suponha que tem a seguinte tabela que contém anúncios de emprego:

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

A palavra competências provavelmente aparece com frequência na coluna job_description, mas raramente na coluna company_name. Suponha que executa a seguinte consulta:

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

Se criou um índice de pesquisa nas colunas company_name e job_description sem especificar a granularidade das colunas, o BigQuery analisaria todos os ficheiros nos quais a palavra skills aparece na coluna job_description ou company_name. Para melhorar o desempenho desta consulta, pode definir a granularidade da coluna para company_name como COLUMN:

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

Agora, quando executar a consulta, o BigQuery apenas analisa os ficheiros nos quais a palavra skills aparece na coluna company_name.

Para ver informações sobre as opções definidas nas colunas de uma tabela indexada, consulte a vista INFORMATION_SCHEMA.SEARCH_INDEX_COLUMN_OPTIONS.

Existem limites para o número de colunas que pode indexar com granularidade de coluna. Para mais informações, consulte o artigo Quotas e limites.

Compreenda a atualização do índice

Os índices de pesquisa são totalmente geridos pelo BigQuery e atualizados automaticamente quando a tabela é alterada. Uma atualização completa do índice pode ocorrer nos seguintes casos:

Caso os dados de uma coluna indexada sejam atualizados em todas as linhas, como durante uma operação de preenchimento, todo o índice tem de ser atualizado, o que equivale a uma atualização completa. Recomendamos que faça os preenchimentos lentamente, como por exemplo, por partição, para minimizar o potencial impacto negativo.

Se fizer alguma alteração ao esquema da tabela base que impeça a indexação de uma coluna indexada explicitamente, o índice é desativado permanentemente.

Se eliminar a única coluna indexada numa tabela ou mudar o nome da própria tabela, o índice de pesquisa é eliminado automaticamente.

Os índices de pesquisa são concebidos para tabelas grandes. Se criar um índice de pesquisa numa tabela com menos de 10 GB, o índice não é preenchido. Da mesma forma, se eliminar dados de uma tabela indexada e o tamanho da tabela ficar abaixo de 10 GB, o índice é desativado temporariamente. Neste caso, as consultas de pesquisa não usam o índice e o código IndexUnusedReason é BASE_TABLE_TOO_SMALL. Isto acontece quer use ou não a sua própria reserva para as tarefas de gestão de índices. Quando o tamanho de uma tabela indexada excede 10 GB, o respetivo índice é preenchido automaticamente. O armazenamento não lhe é cobrado até que o índice de pesquisa seja preenchido e esteja ativo. As consultas que usam a função SEARCH devolvem sempre resultados corretos, mesmo que alguns dados ainda não estejam indexados.

Receba informações sobre os índices de pesquisa

Pode consultar INFORMATION_SCHEMA para verificar a existência e a disponibilidade de um índice de pesquisa. Existem três vistas que contêm metadados sobre os índices de pesquisa.

INFORMATION_SCHEMA.SEARCH_INDEXES veja exemplos

Esta secção inclui exemplos de consultas da vista INFORMATION_SCHEMA.SEARCH_INDEXES.

O exemplo seguinte mostra todos os índices de pesquisa ativos em tabelas no conjunto de dados my_dataset, localizados no projeto my_project. Inclui os respetivos nomes, as declarações DDL usadas para os criar, a percentagem de cobertura e o analisador de texto. Se uma tabela base indexada tiver menos de 10 GB, o respetivo índice não é preenchido. Nesse caso, o valor de 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';

Os resultados devem ter o seguinte aspeto:

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

Esta secção inclui exemplos de consultas da vista INFORMATION_SCHEMA.SEARCH_INDEX_COLUMNS.

O exemplo seguinte cria um índice de pesquisa em todas as colunas de 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);

A seguinte consulta extrai informações sobre os campos que estão indexados. O index_field_path indica o campo de uma coluna que está indexado. Isto difere do index_column_name apenas no caso de um STRUCT, em que é fornecido o caminho completo para o campo indexado. Neste exemplo, a coluna c contém um campo ARRAY<STRING> e e outro STRUCT denominado f, que contém um campo STRING g, cada um dos quais está indexado.

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

O resultado é semelhante ao seguinte:

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

A consulta seguinte junta a vista INFORMATION_SCHEMA.SEARCH_INDEX_COUMNS às vistas INFORMATION_SCHEMA.SEARCH_INDEXES e INFORMATION_SCHEMA.COLUMNS para incluir o estado do índice de pesquisa e o tipo de dados de cada coluna:

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;

O resultado é semelhante ao seguinte:

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

Esta secção inclui exemplos de consultas da vista INFORMATION_SCHEMA.SEARCH_INDEXES_BY_ORGANIZATION.

Descubra se o consumo excede o limite numa determinada região

O exemplo seguinte ilustra o que acontece se o tamanho total da tabela base indexada numa organização, que usa slots partilhados na multirregião dos EUA, exceder 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

O resultado é semelhante ao seguinte:

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

Encontre o tamanho total da tabela base indexada por projetos numa região

O exemplo seguinte apresenta a discriminação de cada projeto numa multirregião dos EUA com o tamanho total das tabelas base indexadas:

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

O resultado é semelhante ao seguinte:

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

Encontre índices de pesquisa limitados

O exemplo seguinte devolve todos os índices de pesquisa que estão limitados na organização e na região:

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

O resultado é semelhante ao seguinte:

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

Opções de gestão de índices

Para criar índices e fazer com que o BigQuery os mantenha, tem duas opções:

  • Use o conjunto de slots partilhados predefinido: quando os dados que planeia indexar estão abaixo do seu limite por organização, pode usar o conjunto de slots partilhados gratuito para a gestão do índice.
  • Use a sua própria reserva: para alcançar um progresso de indexação mais previsível e consistente nas suas cargas de trabalho de produção maiores, pode usar as suas próprias reservas para a gestão de índices.

Use espaços partilhados

Se não tiver configurado o seu projeto para usar uma reserva dedicada para indexação, a gestão de índices é processada no conjunto de slots partilhados gratuito, sujeita às seguintes restrições.

Se adicionar dados a uma tabela que façam com que o tamanho total das tabelas indexadas exceda o limite da sua organização, o BigQuery pausa a gestão de índices para essa tabela. Quando isto acontece, o campo index_status na vista INFORMATION_SCHEMA.SEARCH_INDEXES apresenta PENDING DISABLEMENT e o índice é colocado em fila para eliminação. Enquanto o índice estiver pendente de desativação, continua a ser usado em consultas, e é-lhe cobrado o armazenamento do índice. Após a eliminação do índice, o campo index_status mostra o índice como TEMPORARILY DISABLED. Neste estado, as consultas não usam o índice e não lhe é cobrado o armazenamento do índice. Neste caso, o código IndexUnusedReason é BASE_TABLE_TOO_LARGE.

Se eliminar dados da tabela e o tamanho total das tabelas indexadas ficar abaixo do limite por organização, a gestão de índices é retomada. Se o campo index_status na vista INFORMATION_SCHEMA.SEARCH_INDEXES for ACTIVE, as consultas podem usar o índice e é-lhe cobrado o armazenamento do índice.

Pode usar a vista INFORMATION_SCHEMA.SEARCH_INDEXES_BY_ORGANIZATION para compreender o seu consumo atual em relação ao limite por organização numa determinada região, discriminado por projetos e tabelas.

O BigQuery não oferece garantias sobre a capacidade disponível do conjunto partilhado nem sobre o débito de indexação que vê. Para aplicações de produção, recomendamos que use ranhuras dedicadas para o processamento do índice.

Use a sua própria reserva

Em vez de usar o conjunto de intervalos partilhados predefinido, pode designar opcionalmente a sua própria reserva para indexar as tabelas. A utilização da sua própria reserva garante um desempenho previsível e consistente das tarefas de gestão de índices, como a criação, a atualização e as otimizações em segundo plano.

  • Não existem limites de tamanho da tabela quando uma tarefa de indexação é executada na sua reserva.
  • A utilização da sua própria reserva dá-lhe flexibilidade na gestão do índice. Se precisar de criar um índice muito grande ou fazer uma atualização importante a uma tabela indexada, pode adicionar temporariamente mais espaços à atribuição.

Para indexar as tabelas num projeto com uma reserva designada, crie uma reserva na região onde as tabelas estão localizadas. Em seguida, atribua o projeto à reserva com o valor job_type definido como BACKGROUND:

SQL

Use a CREATE ASSIGNMENT declaração DDL.

  1. Na Google Cloud consola, aceda à página BigQuery.

    Aceda ao BigQuery

  2. No editor de consultas, introduza a seguinte declaração:

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

    Substitua o seguinte:

    • ADMIN_PROJECT_ID: o ID do projeto do projeto de administração que detém o recurso de reserva
    • LOCATION: a localização da reserva
    • RESERVATION_NAME: o nome da reserva
    • ASSIGNMENT_ID: o ID da atribuição

      O ID tem de ser exclusivo do projeto e da localização, começar e terminar com uma letra minúscula ou um número, e conter apenas letras minúsculas, números e traços.

    • PROJECT_ID: o ID do projeto que contém as tabelas a indexar. Este projeto está atribuído à reserva.

  3. Clique em Executar.

Para mais informações sobre como executar consultas, consulte o artigo Execute uma consulta interativa.

bq

Use o 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

Substitua o seguinte:

  • ADMIN_PROJECT_ID: o ID do projeto do projeto de administração que detém o recurso de reserva
  • LOCATION: a localização da reserva
  • RESERVATION_NAME: o nome da reserva
  • PROJECT_ID: o ID do projeto a atribuir a esta reserva

Veja as suas tarefas de indexação

É criado um novo trabalho de indexação sempre que um índice é criado ou atualizado numa única tabela. Para ver informações sobre a tarefa, consulte as vistas INFORMATION_SCHEMA.JOBS*. Pode filtrar tarefas de indexação definindo job_type IS NULL AND SEARCH(job_id, '`search_index`') na cláusula WHERE da sua consulta. O exemplo seguinte apresenta os cinco trabalhos de indexação mais recentes no projeto 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;

Escolha o tamanho da reserva

Para escolher o número certo de vagas para a sua reserva, deve considerar quando os trabalhos de gestão de índices são executados, quantas vagas usam e como é a sua utilização ao longo do tempo. O BigQuery aciona uma tarefa de gestão de índices nas seguintes situações:

  • Cria um índice numa tabela.
  • Os dados são modificados numa tabela indexada.
  • O esquema de uma tabela muda e isto afeta as colunas que são indexadas.
  • Os dados e os metadados do índice são otimizados ou atualizados periodicamente.

O número de ranhuras necessárias para uma tarefa de gestão de índices numa tabela depende dos seguintes fatores:

  • O tamanho da tabela
  • A taxa de carregamento de dados para a tabela
  • A taxa de instruções DML aplicadas à tabela
  • O atraso aceitável para criar e manter o índice
  • A complexidade do índice, normalmente determinada pelos atributos dos dados, como o número de termos duplicados
Estimativa inicial

As seguintes estimativas podem ajudar a aproximar o número de slots que a sua reserva requer. Devido à natureza altamente variável das cargas de trabalho de indexação, deve reavaliar os seus requisitos depois de começar a indexar dados.

  • Dados existentes: com uma reserva de 1000 slots, é possível indexar uma tabela existente no BigQuery a uma taxa média de até 4 GiB por segundo, o que corresponde a aproximadamente 336 TiB por dia.
  • Dados carregados recentemente: normalmente, a indexação é mais intensiva em termos de recursos nos dados carregados recentemente, uma vez que a tabela e o respetivo índice passam por várias rondas de otimizações transformadoras. Em média, a indexação de dados recém-carregados consome três vezes mais recursos em comparação com a indexação de preenchimento inicial dos mesmos dados.
  • Dados modificados com pouca frequência: as tabelas indexadas com poucas ou nenhumas modificações de dados precisam de substancialmente menos recursos para a manutenção contínua do índice. Um ponto de partida recomendado é manter 1/5 dos espaços necessários para a indexação de preenchimento de dados inicial dos mesmos dados e, no mínimo, 250 espaços.
  • O progresso da indexação é aproximadamente linear com o tamanho da reserva. No entanto, não recomendamos a utilização de reservas com menos de 250 espaços para indexação, uma vez que pode levar a ineficiências que podem atrasar o progresso da indexação.
  • Estas estimativas podem mudar à medida que as funcionalidades, as otimizações e a sua utilização real variam.
  • Se o tamanho total da tabela da sua organização exceder o limite de indexação da sua região, deve manter uma reserva diferente de zero atribuída para a indexação. Caso contrário, a indexação pode voltar ao nível predefinido, o que resulta na eliminação não intencional de todos os índices.
Monitorize a utilização e o progresso

A melhor forma de avaliar o número de espaços que precisa para executar eficientemente as suas tarefas de gestão de índices é monitorizar a utilização de espaços e ajustar o tamanho da reserva em conformidade. A seguinte consulta produz a utilização diária de slots para tarefas de gestão de índices. Apenas os últimos 30 dias estão incluídos na região us-west1:

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;

Quando existem slots insuficientes para executar tarefas de gestão de índices, um índice pode ficar dessincronizado com a respetiva tabela e as tarefas de indexação podem falhar. Neste caso, o BigQuery recompila o índice de raiz. Para evitar ter um índice dessincronizado, certifique-se de que tem slots suficientes para suportar as atualizações do índice a partir do carregamento e da otimização de dados. Para mais informações sobre a monitorização da utilização de faixas, consulte os gráficos de recursos de administrador.

Práticas recomendadas

  • Os índices de pesquisa são concebidos para tabelas grandes. Os ganhos de desempenho de um índice de pesquisa aumentam com o tamanho da tabela.
  • Não indexe colunas que contenham apenas um número muito pequeno de valores únicos.
  • Não indexe colunas que nunca pretende usar com a função SEARCH nem com nenhuma das outras funções e operadores suportados.
  • Tenha cuidado ao criar um índice de pesquisa em ALL COLUMNS. Sempre que adiciona uma coluna com dados STRING ou JSON, esta é indexada.
  • Deve usar a sua própria reserva para a gestão de índices em aplicações de produção. Se optar por usar o conjunto de ranhuras partilhadas predefinido para as tarefas de gestão de índices, aplicam-se os limites de dimensionamento por organização.

Elimine um índice de pesquisa

Quando já não precisar de um índice de pesquisa ou quiser alterar as colunas indexadas numa tabela, pode eliminar o índice atualmente nessa tabela. Use a DROP SEARCH INDEX declaração DDL.

Se uma tabela indexada for eliminada, o respetivo índice é eliminado automaticamente.

Exemplo:

DROP SEARCH INDEX my_index ON dataset.simple_table;

O que se segue?

  • Para uma vista geral dos exemplos de utilização, dos preços, das autorizações necessárias e das limitações do índice de pesquisa, consulte a Introdução à pesquisa no BigQuery.
  • Para obter informações sobre a pesquisa eficiente de colunas indexadas, consulte o artigo Pesquise com um índice.