Uso de resultados de consulta armazenados em cache

O BigQuery grava todos os resultados de consulta em uma tabela. Ela é explicitamente identificada pelo usuário (tabela de destino) ou é uma tabela temporária de resultados armazenados em cache. Se você executar a mesma consulta novamente, o BigQuery retornará os resultados da tabela em cache, se houver. Essas tabelas temporárias são mantidas por projeto e por usuário. Dependendo da edição, você pode ter acesso a resultados armazenados em cache de outros usuários que executam consultas no mesmo projeto. Não há custos de armazenamento para as tabelas de resultados de consulta em cache. No entanto, se você gravar os resultados da consulta em uma tabela permanente, será cobrado pelo armazenamento dos dados.

Todos os resultados de consultas, incluindo interativas e em lote, são armazenados em cache em tabelas temporárias por aproximadamente 24 horas, com algumas exceções.

Limitações

O uso do cache de consulta está sujeito às limitações a seguir:

  • Ao executar uma consulta duplicada, o BigQuery tenta reutilizar os resultados armazenados em cache. Para recuperar dados do cache, o texto da consulta duplicada precisa ser exatamente o mesmo da original.
  • Para que os resultados da consulta permaneçam na tabela de resultados armazenados em cache, o conjunto de resultados precisa ser menor que o tamanho máximo da resposta. Para mais informações sobre como gerenciar conjuntos grandes de resultados, consulte Como retornar resultados extensos de consulta.
  • Não é possível apontar para tabelas de resultados armazenados em cache com instruções DML.
  • Embora seja permitido pela semântica atual, o uso de resultados armazenados em cache como entrada para jobs dependentes não é recomendado. Por exemplo, não convém enviar jobs de consulta que recuperam resultados da tabela de cache. Em vez disso, grave os resultados em uma tabela de destino nomeada. Para simplificar a limpeza, é possível que atributos como a propriedade defaultTableExpirationMs no nível do conjunto de dados eliminem os dados automaticamente após o prazo especificado.

Preços e cotas

Os resultados da consulta em cache são armazenados como tabelas temporárias. Não há cobrança pelo armazenamento de resultados de consulta em cache em tabelas temporárias. Quando os resultados da consulta são recuperados de uma tabela de resultados armazenados em cache, a propriedade statistics.query.cacheHit de estatísticas do job é retornada como true e não é feita cobranças pela consulta. Embora não haja cobrança por consultas que usam resultados armazenados em cache, elas estão sujeitas às políticas de cota do BigQuery. Além de reduzir custos, essas consultas são significativamente mais rápidas porque o BigQuery não precisa computar o conjunto de resultados.

Exceções para consultar resultados armazenados em cache

Os resultados de consultas não são armazenados em cache:

  • Quando uma tabela de destino é especificada na configuração do job, no console do Google Cloud, na ferramenta de linha de comando bq ou na API.
  • se qualquer uma das tabelas referenciadas ou visualizações lógicas foi alterada desde que os resultados foram armazenados em cache.
  • Quando qualquer uma das tabelas referenciadas pela consulta receber inserções de streaming recentes (a tabela tem dados no armazenamento otimizado para gravação), mesmo que nenhuma nova linha tenha chegado.
  • Caso a consulta use funções não determinísticas, por exemplo, funções de data e hora, como CURRENT_TIMESTAMP() e CURRENT_DATE, e outras funções, como SESSION_USER(), retornam valores diferentes dependendo de quando uma consulta é executada
  • Se você estiver consultando várias tabelas usando um caractere curinga.
  • Se os resultados armazenados em cache expirarem. A duração comum do cache é de 24 horas, mas os resultados são de esforço máximo e podem ser invalidados antes.
  • Se a consulta for executada em uma fonte de dados externa do Cloud Storage. As consultas do Google SQL no Cloud Storage são compatíveis com os resultados armazenados em cache.
  • Se a consulta for executada em uma tabela protegida pela segurança no nível da coluna, os resultados não poderão ser armazenados em cache.
  • Se a consulta for executada em uma tabela protegida pela segurança no nível da linha, os resultados não serão armazenados em cache.

Como os resultados em cache são armazenados

Quando você executa uma consulta, uma tabela de resultados armazenados em cache temporária é criada em um tipo especial de conjunto de dados oculto conhecido como conjunto de dados anônimo. Ao contrário dos conjuntos de dados regulares, que herdam as permissões do modelo de hierarquia de recursos do IAM (permissões de projeto e de organização), o acesso a conjuntos de dados anônimos é restrito ao proprietário. O proprietário de um conjunto de dados anônimo é o usuário que executou a consulta que produziu o resultado armazenado em cache. Além disso, a permissão bigquery.jobs.create é verificada no projeto para confirmar que o usuário terá acesso a ele.

O BigQuery não oferece suporte ao compartilhamento de conjuntos de dados anônimos. Se você pretende compartilhar resultados de consultas, não use os resultados armazenados em cache em um conjunto de dados anônimo. Em vez disso, grave os resultados em uma tabela de destino nomeada.

O usuário que executa a consulta tem acesso total ao conjunto de dados e à tabela de resultados em cache. No entanto, não é recomendável utilizá-los como entradas para jobs dependentes.

Os nomes de conjuntos de dados anônimos começam com um sublinhado. Isso os oculta da lista de conjuntos de dados no console do Google Cloud. É possível listar conjuntos de dados anônimos e auditar controles de acesso a eles usando a ferramenta de linha de comando bq ou a API.

Para saber como listar e receber informações sobre conjuntos de dados, incluindo conjuntos de dados anônimos, consulte Como listar conjuntos de dados.

Armazenamento em cache entre usuários

Se você estiver usando a edição Enterprise ou Enterprise Plus e tiver as permissões necessárias para executar uma consulta em cache no seu projeto para outro usuário, o BigQuery produzirá o resultado em cache. O resultado armazenado em cache é copiado no seu conjunto de dados anônimo pessoal e permanece nele por 24 horas após a execução da consulta. Os mesmos limites e exceções do armazenamento em cache de um usuário se aplicam ao armazenamento em cache de vários usuários.

Como desativar a recuperação de resultados armazenados em cache

A opção Usar resultados em cache reutiliza os resultados de uma execução anterior da mesma consulta, exceto quando as tabelas que estão sendo consultadas são alteradas. O uso de resultados armazenados em cache é útil somente no caso de consultas repetidas. Para novas consultas, a opção Usar resultados em cache não tem nenhum efeito, embora seja ativada por padrão.

Quando você repete uma consulta com a opção Usar resultados em cache desativada, o resultado atual armazenado em cache é substituído. Para isso, o BigQuery precisa computar o resultado da consulta, e você é cobrado por ela. Esse recurso é útil principalmente em cenários comparativos de mercado.

Para desativar a recuperação de resultados armazenados em cache e forçar a avaliação ativa de um job de consulta, defina a propriedade configuration.query.useQueryCache do job de consulta como false.

Para desativar a opção Usar resultados em cache, siga estas etapas:

Console

  1. Abra o Console do Google Cloud.
    Acesse a página do BigQuery

  2. Clique em Escrever nova consulta.

  3. Insira uma consulta SQL válida na área de texto do Editor de consultas.

  4. Clique em Mais e selecione Configurações de consulta.

    Configurações de consulta

  5. Em Preferência de cache, desmarque Usar resultados em cache.

bq

Use a sinalização nouse_cache para substituir o cache de consulta. O exemplo a seguir força o BigQuery a processar a consulta sem usar os resultados armazenados em cache atuais:

 bq query \
 --nouse_cache \
 --batch \
 'SELECT
    name,
    count
  FROM
    `my-project`.mydataset.names_2013
  WHERE
    gender = "M"
  ORDER BY
    count DESC
  LIMIT
    6'

API

Para processar uma consulta sem usar os resultados armazenados em cache atuais, defina a propriedade useQueryCache como false na configuração do job de query.

Go

Antes de testar esta amostra, siga as instruções de configuração do Go no Guia de início rápido do BigQuery: como usar bibliotecas de cliente. Para mais informações, consulte a documentação de referência da API BigQuery em Go.

Para autenticar no BigQuery, configure o Application Default Credentials. Para mais informações, acesse Configurar a autenticação para bibliotecas de cliente.

import (
	"context"
	"fmt"
	"io"

	"cloud.google.com/go/bigquery"
	"google.golang.org/api/iterator"
)

// queryDisableCache demonstrates issuing a query and requesting that the query cache is bypassed.
func queryDisableCache(w io.Writer, projectID string) error {
	// projectID := "my-project-id"
	ctx := context.Background()
	client, err := bigquery.NewClient(ctx, projectID)
	if err != nil {
		return fmt.Errorf("bigquery.NewClient: %v", err)
	}
	defer client.Close()

	q := client.Query(
		"SELECT corpus FROM `bigquery-public-data.samples.shakespeare` GROUP BY corpus;")
	q.DisableQueryCache = true
	// Location must match that of the dataset(s) referenced in the query.
	q.Location = "US"

	// Run the query and print results when the query job is completed.
	job, err := q.Run(ctx)
	if err != nil {
		return err
	}
	status, err := job.Wait(ctx)
	if err != nil {
		return err
	}
	if err := status.Err(); err != nil {
		return err
	}
	it, err := job.Read(ctx)
	for {
		var row []bigquery.Value
		err := it.Next(&row)
		if err == iterator.Done {
			break
		}
		if err != nil {
			return err
		}
		fmt.Fprintln(w, row)
	}
	return nil
}

Java

Para processar uma consulta sem usar os resultados armazenados em cache atuais, defina o uso do cache de consulta como false ao criar um QueryJobConfiguration (páginas em inglês).

import com.google.cloud.bigquery.BigQuery;
import com.google.cloud.bigquery.BigQueryException;
import com.google.cloud.bigquery.BigQueryOptions;
import com.google.cloud.bigquery.QueryJobConfiguration;
import com.google.cloud.bigquery.TableResult;

// Sample to running a query with the cache disabled.
public class QueryDisableCache {

  public static void runQueryDisableCache() {
    String query = "SELECT corpus FROM `bigquery-public-data.samples.shakespeare` GROUP BY corpus;";
    queryDisableCache(query);
  }

  public static void queryDisableCache(String query) {
    try {
      // Initialize client that will be used to send requests. This client only needs to be created
      // once, and can be reused for multiple requests.
      BigQuery bigquery = BigQueryOptions.getDefaultInstance().getService();

      QueryJobConfiguration queryConfig =
          QueryJobConfiguration.newBuilder(query)
              // Disable the query cache to force live query evaluation.
              .setUseQueryCache(false)
              .build();

      TableResult results = bigquery.query(queryConfig);

      results
          .iterateAll()
          .forEach(row -> row.forEach(val -> System.out.printf("%s,", val.toString())));

      System.out.println("Query disable cache performed successfully.");
    } catch (BigQueryException | InterruptedException e) {
      System.out.println("Query not performed \n" + e.toString());
    }
  }
}

Node.js

Antes de testar esta amostra, siga as instruções de configuração do Node.js no Guia de início rápido do BigQuery: como usar bibliotecas de cliente. Para mais informações, consulte a documentação de referência da API BigQuery em Node.js.

Para autenticar no BigQuery, configure o Application Default Credentials. Para mais informações, acesse Configurar a autenticação para bibliotecas de cliente.

// Import the Google Cloud client library
const {BigQuery} = require('@google-cloud/bigquery');

async function queryDisableCache() {
  // Queries the Shakespeare dataset with the cache disabled.

  // Create a client
  const bigquery = new BigQuery();

  const query = `SELECT corpus
    FROM \`bigquery-public-data.samples.shakespeare\`
    GROUP BY corpus`;
  const options = {
    query: query,
    // Location must match that of the dataset(s) referenced in the query.
    location: 'US',
    useQueryCache: false,
  };

  // Run the query as a job
  const [job] = await bigquery.createQueryJob(options);
  console.log(`Job ${job.id} started.`);

  // Wait for the query to finish
  const [rows] = await job.getQueryResults();

  // Print the results
  console.log('Rows:');
  rows.forEach(row => console.log(row));
}

PHP

Antes de testar esta amostra, siga as instruções de configuração do PHP no Guia de início rápido do BigQuery: como usar bibliotecas de cliente. Para mais informações, consulte a documentação de referência da API BigQuery em PHP.

Para autenticar no BigQuery, configure o Application Default Credentials. Para mais informações, acesse Configurar a autenticação para bibliotecas de cliente.

use Google\Cloud\BigQuery\BigQueryClient;

/** Uncomment and populate these variables in your code */
// $projectId = 'The Google project ID';
// $query = 'SELECT id, view_count FROM `bigquery-public-data.stackoverflow.posts_questions`';

// Construct a BigQuery client object.
$bigQuery = new BigQueryClient([
    'projectId' => $projectId,
]);

// Set job configs
$jobConfig = $bigQuery->query($query);
$jobConfig->useQueryCache(false);

// Extract query results
$queryResults = $bigQuery->runQuery($jobConfig);

$i = 0;
foreach ($queryResults as $row) {
    printf('--- Row %s ---' . PHP_EOL, ++$i);
    foreach ($row as $column => $value) {
        printf('%s: %s' . PHP_EOL, $column, json_encode($value));
    }
}
printf('Found %s row(s)' . PHP_EOL, $i);

Python

Antes de testar esta amostra, siga as instruções de configuração do Python no Guia de início rápido do BigQuery: como usar bibliotecas de cliente. Para mais informações, consulte a documentação de referência da API BigQuery em Python.

Para autenticar no BigQuery, configure o Application Default Credentials. Para mais informações, acesse Configurar a autenticação para bibliotecas de cliente.

from google.cloud import bigquery

# Construct a BigQuery client object.
client = bigquery.Client()

job_config = bigquery.QueryJobConfig(use_query_cache=False)
sql = """
    SELECT corpus
    FROM `bigquery-public-data.samples.shakespeare`
    GROUP BY corpus;
"""
query_job = client.query(sql, job_config=job_config)  # Make an API request.

for row in query_job:
    print(row)

Garantia de uso do cache

Se você usa o método jobs.insert para executar uma consulta, pode forçar a falha de um job de consulta, a menos que os resultados armazenados em cache possam ser usados definindo a propriedade createDisposition A configuração do job query para CREATE_NEVER.

Quando não há resultado de consulta no cache, o erro NOT_FOUND é retornado.

bq

Use a sinalização --require_cache para exigir resultados do cache de consultas. O exemplo a seguir força o BigQuery a processar a consulta se os resultados existirem no cache:

 bq query \
 --require_cache \
 --batch \
 'SELECT
    name,
    count
  FROM
    `my-project`.mydataset.names_2013
  WHERE
    gender = "M"
  ORDER BY
    count DESC
  LIMIT
    6'

API

Para processar uma consulta com os resultados armazenados em cache, defina a propriedade createDisposition como CREATE_NEVER na configuração do job query.

Como verificar o uso do cache

Há duas maneiras de determinar se o BigQuery retornou um resultado usando o cache:

  • Como usar o console do Google Cloud Acesse Resultados da consulta e clique em Informações do job. Bytes processados mostram 0 B (resultados armazenados em cache).
  • Como usar a API BigQuery. A propriedade cacheHit no resultado da consulta é definida como true.

Impacto da segurança no nível da coluna

Por padrão, o BigQuery armazena em cache os resultados da consulta por 24 horas, observando-se as exceções anteriores. As consultas em uma tabela protegida por segurança no nível da coluna podem não ser armazenadas em cache. Se o BigQuery armazenar o resultado em cache, o ciclo de vida de cache de 24 horas será aplicado.

Uma alteração como remover um grupo ou um usuário do papel Leitor de controle granular do Data Catalog usado para uma tag de política não invalida o cache de 24 horas. Uma alteração no grupo de controle de acesso Leitor de controle granular do Data Catalog propriamente dito é propagada imediatamente, mas a alteração não invalida o cache.

O impacto disso é que, caso o usuário tenha realizado uma consulta, os resultados dela permanecem visíveis na tela. O usuário também pode recuperar esses resultados do cache, mesmo que tenha perdido o acesso aos dados nas últimas 24 horas.

Nas 24 horas após um usuário ser removido do papel Leitor de controle granular do Data Catalog para uma tag da política, ele só terá acesso aos dados armazenados em cache que já tinha permissão para ver antes. Se as linhas forem adicionadas à tabela, o usuário não conseguirá ver as linhas adicionadas, mesmo que os resultados sejam armazenados em cache.