Como controlar custos no BigQuery

Veja nesta página as práticas recomendadas para controlar custos no BigQuery.

O BigQuery tem dois modelos de preços para executar consultas:

  • Preços sob demanda: você paga pela quantidade de bytes processados por cada consulta.
  • Preços fixos: você paga pela capacidade dedicada de processamento da consulta, medida em slots.

Se você estiver usando preços sob demanda, você poderá reduzir custos diretamente reduzindo o número de bytes processados por uma consulta. Com o preço de taxa fixa, seu custo é fixo com base no número de slots adquiridos e no plano de compromisso de slot selecionado. No entanto, otimizar as consultas pode ajudar a reduzir o uso de slots.

Evite SELECT *

Prática recomendada: consulte somente as colunas necessárias.

Usar SELECT * é a maneira mais cara de consultar dados. Quando você usa SELECT *, o BigQuery faz uma verificação completa de todas as colunas da tabela.

Se você estiver testando ou explorando dados, use uma das opções de visualização de dados em vez de SELECT *.

A aplicação de uma cláusula LIMIT a uma consulta SELECT * não afeta a quantidade de dados lidos. A cobrança ocorre em relação à leitura de todos os bytes em toda a tabela, e a consulta é contabilizada na sua cota de nível gratuito.

Em vez disso, consulte apenas as colunas de que você precisa. Por exemplo, use SELECT * EXCEPT para excluir uma ou mais colunas dos resultados.

Se você precisar fazer a consulta em todas as colunas de uma tabela, mas apenas em um subconjunto de dados, faça o seguinte:

  • materializar os resultados em uma tabela de destino e realizar a consulta nessa tabela;
  • Particione suas tabelas por data e consulte a partição relevante. Por exemplo, WHERE _PARTITIONDATE="2017-01-01" analisa somente a partição de 1º de janeiro de 2017.

Dados de amostra com opções de visualização

Prática recomendada: não faça consultas para explorar ou visualizar dados da tabela.

Se você estiver fazendo testes ou explorando dados, pode usar a opção de visualização da tabela para visualizar dados gratuitamente sem afetar suas cotas.

O BigQuery é compatível com as opções de visualização de dados a seguir:

  • No Console do Cloud, na página de detalhes da tabela, clique na guia Visualizar para criar amostras dos dados.
  • Na ferramenta de linha de comando bq, use o comando bq head e especifique o número de linhas que quer visualizar.
  • Na API, use tabledata.list para recuperar os dados da tabela de um conjunto de linhas especificado.

Calcular o preço das consultas antes de executá-las

Prática recomendada: antes de executar consultas, visualize-as para tentar estimar os custos.

As consultas são cobradas de acordo com o número de bytes lidos. Para estimar custos antes de executar uma consulta:

  • Visualize o validador de consultas no Console do Cloud
  • Use a Calculadora de preços do Google Cloud Platform.
  • Execute uma simulação usando:
    • Sinalização --dry_run na ferramenta de linha de comando bq
    • o parâmetro dryRun ao enviar um job de consulta usando a API

Como usar o validador de consulta

Quando você insere uma consulta no Console do Cloud, o validador de consulta verifica a sintaxe dela e fornece uma estimativa do número de bytes lidos. Esta estimativa pode ser usada para calcular o custo da consulta na calculadora de preços.

  • Se a consulta não for válida, o validador de consultas exibirá uma mensagem de erro. Exemplo:

    Not found: Table myProject:myDataset.myTable was not found in location US

  • Se a consulta for válida, o validador de consulta fornecerá uma estimativa do número de bytes necessários para processar a consulta. Exemplo:

    This query will process 623.1 KiB when run.

Como executar uma simulação

Para executar uma simulação:

Console

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

    Ir para o BigQuery

  2. Digite a consulta no Editor de consultas.

    Se a consulta for válida, uma marca de seleção será exibida junto com a quantidade de dados que serão processados pela consulta. Se a consulta for inválida, um ponto de exclamação será exibido com uma mensagem de erro.

bq

Insira uma consulta como a seguinte usando a sinalização --dry_run.

bq query \
--use_legacy_sql=false \
--dry_run \
'SELECT
   COUNTRY,
   AIRPORT,
   IATA
 FROM
   `project_id`.dataset.airports
 LIMIT
   1000'
 

O comando gera a resposta a seguir:

Query successfully validated. Assuming the tables are not modified,
running this query will process 10918 bytes of data.

API

Para executar uma simulação usando a API, envie um job de consulta com dryRun definido como true no tipo JobConfiguration.

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.

import (
	"context"
	"fmt"
	"io"

	"cloud.google.com/go/bigquery"
)

// queryDryRun demonstrates issuing a dry run query to validate query structure and
// provide an estimate of the bytes scanned.
func queryDryRun(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
		name,
		COUNT(*) as name_count
	FROM ` + "`bigquery-public-data.usa_names.usa_1910_2013`" + `
	WHERE state = 'WA'
	GROUP BY name`)
	q.DryRun = true
	// Location must match that of the dataset(s) referenced in the query.
	q.Location = "US"

	job, err := q.Run(ctx)
	if err != nil {
		return err
	}
	// Dry run is not asynchronous, so get the latest status and statistics.
	status := job.LastStatus()
	if err := status.Err(); err != nil {
		return err
	}
	fmt.Fprintf(w, "This query will process %d bytes\n", status.Statistics.TotalBytesProcessed)
	return nil
}

Java

Antes de testar esta amostra, siga as instruções de configuração do Java 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 Java.

import com.google.cloud.bigquery.BigQuery;
import com.google.cloud.bigquery.BigQueryException;
import com.google.cloud.bigquery.BigQueryOptions;
import com.google.cloud.bigquery.Job;
import com.google.cloud.bigquery.JobInfo;
import com.google.cloud.bigquery.JobStatistics;
import com.google.cloud.bigquery.QueryJobConfiguration;

// Sample to run dry query on the table
public class QueryDryRun {

  public static void runQueryDryRun() {
    String query =
        "SELECT name, COUNT(*) as name_count "
            + "FROM `bigquery-public-data.usa_names.usa_1910_2013` "
            + "WHERE state = 'WA' "
            + "GROUP BY name";
    queryDryRun(query);
  }

  public static void queryDryRun(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).setDryRun(true).setUseQueryCache(false).build();

      Job job = bigquery.create(JobInfo.of(queryConfig));
      JobStatistics.QueryStatistics statistics = job.getStatistics();

      System.out.println(
          "Query dry run performed successfully." + statistics.getTotalBytesProcessed());
    } catch (BigQueryException 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 Node.js.

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

async function queryDryRun() {
  // Runs a dry query of the U.S. given names dataset for the state of Texas.

  const query = `SELECT name
    FROM \`bigquery-public-data.usa_names.usa_1910_2013\`
    WHERE state = 'TX'
    LIMIT 100`;

  // For all options, see https://cloud.google.com/bigquery/docs/reference/rest/v2/jobs/query
  const options = {
    query: query,
    // Location must match that of the dataset(s) referenced in the query.
    location: 'US',
    dryRun: true,
  };

  // Run the query as a job
  const [job] = await bigquery.createQueryJob(options);

  // Print the status and statistics
  console.log('Status:');
  console.log(job.metadata.status);
  console.log('\nJob Statistics:');
  console.log(job.metadata.statistics);
}

Python

Para executar uma simulação usando a biblioteca de cliente em Python, configure a propriedade QueryJobConfig.dry_run como True. Se uma configuração de consulta de simulação for fornecida, Client.query() sempre retornará um QueryJob concluído (links em inglês).

Antes de testar essa amostra, siga as instruções de configuração para 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.

from google.cloud import bigquery

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

job_config = bigquery.QueryJobConfig(dry_run=True, use_query_cache=False)

# Start the query, passing in the extra configuration.
query_job = client.query(
    (
        "SELECT name, COUNT(*) as name_count "
        "FROM `bigquery-public-data.usa_names.usa_1910_2013` "
        "WHERE state = 'WA' "
        "GROUP BY name"
    ),
    job_config=job_config,
)  # Make an API request.

# A dry run query completes immediately.
print("This query will process {} bytes.".format(query_job.total_bytes_processed))

Usar a calculadora de preços

Para estimar os custos da consulta na Calculadora de preços do Google Cloud Platform, insira o número de bytes processados pela consulta em MB, GB, TB ou PB. Se ela processar menos de 1 TB, a estimativa será US$ 0, já que o BigQuery fornece processamento sob demanda de 1 TB gratuito por mês.

Calculadora de preços

Limitar os custos de consulta restringindo o número de bytes cobrados

Prática recomendada: use a configuração máxima de bytes cobrados para limitar os custos de consulta.

Você pode limitar o número de bytes cobrados para uma consulta usando a configuração máxima de bytes cobrados. Quando você define o máximo de bytes cobrados, o número de bytes lidos pela consulta é estimado antes da execução da consulta. Se o número de bytes estimados estiver além do limite, a consulta falhará sem gerar cobranças.

Para tabelas em cluster, a estimativa do número de bytes cobrados para uma consulta é um limite superior e pode ser maior que o número real de bytes cobrados depois de executar a consulta. Em alguns casos, se você definir o máximo de bytes cobrados, uma consulta em uma tabela em cluster poderá falhar, mesmo que os bytes reais faturados não excedam a configuração máxima de bytes cobrados.

Se uma consulta apresentar falha devido à configuração máxima de bytes cobrados, um erro como este será retornado:

Error: Query exceeded limit for bytes billed: 1000000. 10485760 or higher required.

Para definir o máximo de bytes cobrados:

Console

  1. No Editor de consultas, clique em Mais, em Configurações de consulta e em Opções avançadas.
  2. No campo Máximo de bytes faturados, insira um número inteiro.
  3. Clique em Save.

bq

Use o comando bq querycom a sinalização --maximum_bytes_billed.

  bq query --maximum_bytes_billed=1000000 \
  --use_legacy_sql=false \
  'SELECT
     word
   FROM
     `bigquery-public-data`.samples.shakespeare'

API

Defina a propriedade maximumBytesBilled em JobConfigurationQuery ou QueryRequest.

Usar tabelas em cluster ou particionadas

Prática recomendada: use clustering e particionamento para reduzir a quantidade de dados verificados.

Clustering e particionamento podem ajudar a reduzir a quantidade de dados processados por consultas. Para limitar o número de partições verificadas ao consultar tabelas em cluster ou particionadas, use um filtro de predicado.

Quando você executa uma consulta em uma tabela em cluster e a consulta inclui um filtro nas colunas em cluster, o BigQuery usa a expressão de filtro e os metadados do bloco para remover os blocos verificados pela consulta. Para mais informações, consulte Como consultar tabelas em clusters.

Ao consultar tabelas particionadas, os filtros na coluna de particionamento são usados para remover as partições. Isso pode reduzir o custo da consulta. Para mais informações, acesse Como consultar tabelas particionadas.

Não use LIMIT para controlar custos em tabelas que não estão em cluster

Prática recomendada: para tabelas que não estão em cluster, não use uma cláusula LIMIT como método de controle de custos.

Para tabelas que não estão em cluster, aplicar uma cláusula LIMIT a uma consulta não afeta a quantidade de dados lidos. Você é cobrado pela leitura de todos os bytes em toda a tabela conforme indicado pela consulta, mesmo que ela retorne apenas um subconjunto. Com uma tabela em cluster, uma cláusula LIMIT pode reduzir o número de bytes verificados.

Ver os custos usando um painel e consultar os registros de auditoria

Prática recomendada: crie um painel para visualizar seus dados de cobrança e faça ajustes no uso do BigQuery. Você também pode transmitir seus registros de auditoria ao BigQuery para analisar os padrões de uso.

É possível exportar os dados de faturamento para o BigQuery e visualizá-los em uma ferramenta, como o Google Data Studio. Para ver um tutorial sobre como criar um painel de faturamento, consulte Visualizar o faturamento do GCP usando o BigQuery e o Google Data Studio (em inglês).

É possível também fazer streaming dos registros de auditoria para o BigQuery e analisá-los para verificar os padrões de uso, como custos de consulta por usuário.

Particionar dados por data

Prática recomendada: particione suas tabelas por data.

Se possível, particione suas tabelas do BigQuery por data. Dessa forma, é possível consultar subconjuntos de dados relevantes, a fim de melhorar o desempenho e reduzir os custos.

Por exemplo, quando você consultar tabelas particionadas, use a pseudocoluna _PARTITIONTIME para filtrar por uma data ou um intervalo de datas. A consulta processa dados apenas nas partições especificadas pela data ou intervalo.

Materializar os resultados da consulta em etapas

Prática recomendada: se possível, materialize os resultados da consulta em etapas.

Se você criar uma consulta grande e de vários estágios, cada vez que você a executar, o BigQuery lerá todos os dados exigidos por ela. A cobrança será realizada com base em todos os dados lidos sempre que a consulta for executada.

Em vez disso, divida sua consulta em etapas de modo que cada uma materialize os resultados da consulta, gravando-os em uma tabela de destino. Consultar a tabela de destino menor reduz a quantidade de dados lidos e reduz os custos. O custo de armazenamento de resultados materializados é muito inferior ao custo do processamento de grandes quantidades de dados.

Considerar o custo de grandes conjuntos de resultados

Prática recomendada: se você estiver gravando grandes resultados de consulta em uma tabela de destino, use o prazo de validade padrão da tabela para remover os dados quando não forem mais necessários.

Manter grandes conjuntos de resultados armazenados no BigQuery gera um custo. Se você não precisa de acesso permanente aos resultados, use a expiração padrão da tabela para excluir os dados automaticamente para você.

Para mais informações, consulte preços de armazenamento.

Usar inserções de streaming com cautela

Prática recomendada: use as inserções de streaming somente se for necessário que seus dados estejam imediatamente disponíveis.

Não há cobranças para carregar dados no BigQuery. No entanto, há cobranças para transmitir dados ao BigQuery. A menos que precisem estar prontamente disponíveis, carregue os dados em vez de transmiti-los.