Estimer les coûts du stockage et des requêtes

Les requêtes à la demande sont facturées en fonction du nombre d'octets lus. Pour connaître le tarif des requêtes à la demande, consultez la page des tarifs.

Pour estimer le coût d'une requête avant de l'exécuter, vous pouvez utiliser les outils suivants :

  • Outil de validation des requêtes dans Cloud Console
  • Option --dry_run dans l'outil de ligne de commande bq
  • Paramètre dryRun lors de l'envoi d'une tâche de requête à l'aide de l'API
  • Simulateur de coût Google Cloud
  • Bibliothèques clientes

Estimer les coûts des requêtes

Pour estimer les coûts des requêtes :

Console

Lorsque vous saisissez une requête dans Cloud Console, l'outil de validation des requêtes valide sa syntaxe et fournit une estimation du nombre d'octets lus. Vous pouvez vous servir de cette estimation pour calculer le coût de la requête dans le Simulateur de coût.

Outil de validation des requêtes

bq

Lorsque vous exécutez une requête dans l'outil de ligne de commande bq, vous pouvez estimer le nombre d'octets lus à l'aide de l'option --dry_run. Vous pouvez vous servir de cette estimation pour calculer le coût de la requête dans le Simulateur de coût.

Voici un exemple de requête dans l'outil bq qui utilise l'option --dry_run :

bq query \
--use_legacy_sql=false \
--dry_run \
'SELECT
  column1,
  column2,
  column3
FROM
  `project_id.dataset.table`
LIMIT
  1000'

Lorsque vous exécutez la commande, la réponse contient une estimation des octets lus : Query successfully validated. Assuming the tables are not modified, running this query will process 10918 bytes of data..

API

Pour effectuer une simulation à l'aide de l'API, envoyez une tâche de requête en définissant le paramètre dryRun sur true.

go

Avant d'essayer l'exemple ci-dessous, suivez la procédure de configuration pour Go décrite dans le guide de démarrage rapide de BigQuery : Utiliser les bibliothèques clientes. Pour en savoir plus, consultez la documentation de référence de l'API BigQuery en langage 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 != nil {
		return err
	}
	fmt.Fprintf(w, "This query will process %d bytes\n", status.Statistics.TotalBytesProcessed)
	return nil
}

Java

Avant d'essayer l'exemple ci-dessous, suivez la procédure de configuration pour Java décrite dans le guide de démarrage rapide de BigQuery : Utiliser les bibliothèques clientes. Pour en savoir plus, consultez la documentation de référence de l'API BigQuery en langage 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

Avant d'essayer l'exemple ci-dessous, suivez la procédure de configuration pour Node.js décrite dans le guide de démarrage rapide de BigQuery : Utiliser les bibliothèques clientes. Pour en savoir plus, consultez la documentation de référence de l'API BigQuery en langage 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

Avant d'essayer l'exemple ci-dessous, suivez la procédure de configuration pour Python décrite dans le guide de démarrage rapide de BigQuery : Utiliser les bibliothèques clientes. Pour en savoir plus, consultez la documentation de référence de l'API BigQuery en langage Python.

Pour effectuer une simulation avec la bibliothèque cliente Python, définissez la propriété QueryJobConfig.dry_run sur True. La méthode Client.query() renvoie toujours une tâche QueryJob terminée lorsque vous lui transmettez une configuration de requête simulée.
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))

Estimer le coût d'une requête à l'aide du simulateur de coût Google Cloud

Pour estimer le coût des requêtes à la demande dans le simulateur de coût Google Cloud, saisissez le nombre d'octets traités par la requête en utilisant l'une des unités suivantes : octets, Ko, Mo, Go, To ou Po. Si votre requête traite moins de 1 To, l'estimation est de 0 $, car BigQuery fournit gratuitement 1 To de traitement de requêtes à la demande par mois.

Simulateur de coût

Pour estimer le coût d'une requête avec le Simulateur de coût :

  1. Ouvrez le simulateur de coût Google Cloud.
  2. Cliquez sur BigQuery.
  3. Cliquez sur l'onglet À la demande.
  4. Dans le champ Nom de la table, saisissez le nom de la table. Exemple : airports.
  5. Pour Storage pricing (Tarifs de stockage), saisissez 0 dans le champ Storage (Stockage).
  6. Dans le champ Tarif des requêtes, entrez l'estimation des octets lus, provenant de votre simulation ou de l'outil de validation des requêtes. Simulateur
  7. Cliquez sur Ajouter à l'estimation.
  8. L'estimation apparaît à droite. Vous pouvez envoyer l'estimation par e-mail ou l'enregistrer. Simulateur à la demande

Dans cet exemple, le nombre d'octets lus est inférieur au quota de 1 To de traitement de requêtes à la demande inclus dans la version gratuite. Le coût est donc estimé à 0 $.

Inclure la tarification forfaitaire dans le Simulateur de coût

Si vous appliquez une tarification forfaitaire à votre compte de facturation, vous pouvez cliquer sur l'onglet Flat-Rate (Taux fixe), choisir votre forfait et ajouter vos coûts de stockage à l'estimation.

Simulateur de taux fixe

Pour en savoir plus, consultez l'article Tarifs forfaitaires.

Estimer les coûts de stockage à l'aide du simulateur de coût Google Cloud

Pour estimer les coûts de stockage dans le simulateur de coût Google Cloud, saisissez le nombre d'octets stockés en utilisant l'une des unités suivantes : octets, Ko, Mo, Go, To ou Po. BigQuery fournit gratuitement 10 Go de stockage chaque mois.

Pour estimer les coûts de stockage avec le Simulateur de coût :

  1. Ouvrez le simulateur de coût Google Cloud.
  2. Cliquez sur BigQuery.
  3. Cliquez sur l'onglet À la demande.
  4. Dans le champ Nom de la table, saisissez le nom de la table. Exemple : airports.
  5. Pour Tarifs de stockage, saisissez 100 dans le champ Stockage. Laissez l'unité de mesure définie sur GB (Go).
  6. Cliquez sur Ajouter à l'estimation.
  7. L'estimation apparaît à droite. Vous pouvez envoyer l'estimation par e-mail ou l'enregistrer. Simulateur de coût

Calcul de la taille des requêtes

Cette section explique comment calculer le nombre d'octets traités par différents types de requêtes à l'aide du modèle de facturation à la demande.

Instructions LMD

Si vous utilisez la facturation à la demande, BigQuery facture les instructions de langage de manipulation de données (LMD) en fonction du nombre d'octets traités par l'instruction.

Pour les tables non partitionnées, le nombre d'octets traités est calculé comme suit :

Instruction LMD Octets traités
INSERT Le nombre total d'octets traités pour toutes les colonnes référencées dans les tables analysées par la requête.
UPDATE Le nombre total d'octets de toutes les colonnes référencées dans les tables analysées par la requête
+ le nombre total d'octets de toutes les colonnes de la table mise à jour au moment où la fonction UPDATE démarre.
DELETE Le nombre total d'octets de toutes les colonnes référencées dans les tables analysées par la requête
+ le nombre total d'octets de toutes les colonnes de la table modifiée au moment où la fonction DELETE démarre.
MERGE S'il y a uniquement des clauses INSERT dans l'instruction MERGE, le nombre total d'octets traités pour toutes les colonnes référencées dans toutes les tables analysées par la requête vous sera facturé.
Si une clause UPDATE ou DELETE est présente dans l'instruction MERGE, le nombre total d'octets traités pour toutes les colonnes référencées dans les tables sources analysées par la requête
+ le nombre total d'octets de toutes les colonnes de la table cible (au démarrage de la fonction MERGE) vous sont facturés.

Pour les tables partitionnées, le nombre d'octets traités est calculé comme suit :

Instruction LMD Octets traités
INSERT Le nombre total d'octets traités pour toutes les colonnes référencées dans toutes les partitions analysées par la requête.
UPDATE Le nombre total d'octets traités pour toutes les colonnes référencées dans toutes les partitions des tables analysées par la requête
+ le nombre total d'octets de toutes les colonnes des partitions mises à jour ou analysées pour la table en cours de mise à jour (au démarrage de la fonction UPDATE).
DELETE Le nombre total d'octets traités pour toutes les colonnes référencées dans toutes les partitions des tables analysées par la requête
+ le nombre total d'octets de toutes les colonnes des partitions modifiées ou analysées pour la table en cours de modification (au démarrage de la fonction DELETE).
MERGE S'il y a uniquement des clauses INSERT dans l'instruction MERGE, le nombre total d'octets traités pour toutes les colonnes référencées dans toutes les partitions analysées par la requête vous sera facturé.
Si une clause UPDATE ou DELETE est présente dans l'instruction MERGE, le nombre total d'octets traités pour toutes les colonnes référencées dans toutes les partitions des tables sources analysées par la requête
+ le nombre total d'octets de toutes les colonnes des partitions mises à jour, supprimées ou analysées pour la table cible (au démarrage de la fonction MERGE) vous sont facturés.

Instructions LDD

Si vous utilisez la facturation à la demande, BigQuery facture les requêtes LDD (langage de définition de données) en fonction du nombre d'octets traités par la requête.

Instruction LDD Octets traités
CREATE TABLE Aucun
CREATE TABLE ... AS SELECT ... Le nombre total d'octets traités pour toutes les colonnes référencées dans les tables analysées par la requête.
CREATE VIEW Aucun
DROP TABLE Aucun
DROP VIEW Aucun

Créer des scripts

Si vous utilisez la facturation à la demande, BigQuery facture le script en fonction du nombre d'octets traités lors de l'exécution du script.

La tarification suivante s'applique aux types d'instructions spécifiques aux scripts :

  • DECLARE : nombre total d'octets scannés pour toutes les tables référencées dans l'expression DEFAULT. Les instructions DECLARE sans références de table n'entraînent aucuns frais.
  • SET : nombre total d'octets scannés pour toutes les tables référencées dans l'expression. Les instructions SET sans références de table n'entraînent aucuns frais.
  • IF : nombre total d'octets scannés pour toutes les tables référencées dans l'expression de condition. Les expressions de condition IF sans références de table n'entraînent aucuns frais. Une instruction non exécutée dans le bloc IF n'entraîne aucuns frais.
  • WHILE : nombre total d'octets scannés pour toutes les tables référencées dans l'expression de condition. Les instructions WHILE sans références de table dans l'expression de condition n'entraînent aucuns frais. Une instruction non exécutée dans le bloc WHILE n'entraîne aucuns frais.
  • CONTINUE ou ITERATE : aucuns frais associés.
  • BREAK ou LEAVE : aucuns frais associés.
  • BEGIN ou END : aucuns frais associés.

Les tables temporaires n'entraînent pas de frais de stockage pendant l'exécution du script. Toutefois, la tarification normale s'applique pour toute instruction qui crée, modifie ou interroge ces tables.

Si un script échoue, le coût des instructions effectuées jusqu'au moment de l'échec vous est facturé. Les instructions qui échouent n'entraînent aucuns frais.

Exemple de tarification d'un script

Dans le script ci-dessous, chaque instruction est précédée d'un commentaire détaillant, le cas échéant, les frais qui lui sont associés.

-- No cost, since no tables are referenced.
DECLARE x DATE DEFAULT CURRENT_DATE();
-- Incurs the cost of scanning string_col from dataset.table.
DECLARE y STRING DEFAULT (SELECT MAX(string_col) FROM dataset.table);
-- Incurs the cost of copying the data from dataset.big_table.  Once the
-- table is created, you are not charged for storage while the rest of the
-- script runs.
CREATE TEMP TABLE t AS SELECT * FROM dataset.big_table;
-- Incurs the cost of scanning column1 from temporary table t.
SELECT column1 FROM t;
-- No cost, since y = 'foo' doesn't reference a table.
IF y = 'foo' THEN
  -- Incurs the cost of scanning all columns from dataset.other_table, if
  -- y was equal to 'foo', or otherwise no cost since it is not executed.
  SELECT * FROM dataset.other_table;
ELSE
  -- Incurs the cost of scanning all columns from dataset.different_table, if
  -- y was not equal to 'foo', or otherwise no cost since it is not executed.
  UPDATE dataset.different_table
  SET col = 10
  WHERE true;
END IF;
-- Incurs the cost of scanning date_col from dataset.table for each
-- iteration of the loop.
WHILE x < (SELECT MIN(date_col) FROM dataset.table) DO
  -- No cost, since the expression does not reference any tables.
  SET x = DATE_ADD(x, INTERVAL 1 DAY);
  -- No cost, since the expression does not reference any tables.
  IF true THEN
    -- LEAVE has no associated cost.
    LEAVE;
  END IF;
  -- Never executed, since the IF branch is always taken, so does not incur
  -- a cost.
  SELECT * FROM dataset.big_table;
END WHILE;

Tables en cluster

Pour vous aider à réduire le coût des requêtes, les tables en cluster éliminent des données de façon qu'elles ne soient pas traitées par les requêtes. Ce processus est appelé "élimination en bloc".

Élimination en bloc

BigQuery trie les données d'une table en cluster en fonction des valeurs des colonnes de clustering, puis les organise en blocs.

Lorsque vous exécutez une requête sur une table en cluster et qu'elle inclut un filtre sur les colonnes en cluster, BigQuery utilise l'expression de filtre et les métadonnées de bloc pour restreindre le nombre de blocs analysés par la requête. Cela permet à BigQuery d'analyser uniquement les blocs pertinents.

Lorsqu'un bloc est éliminé, il n'est pas analysé. Seuls les blocs analysés sont pris en compte pour calculer les octets de données traités par la requête. Le nombre d'octets traités par une requête sur une table en cluster est égal à la somme des octets lus dans chaque colonne référencée par la requête dans les blocs analysés.

Si une table en cluster est référencée à de multiples reprises dans une requête qui utilise plusieurs filtres, BigQuery facture l'analyse des colonnes des blocs appropriés de chacun des filtres respectifs.

Exemple de tarification des tables en cluster

Vous disposez d'une table en cluster nommée ClusteredSalesData. La table est partitionnée en fonction de la colonne timestamp. Elle est par ailleurs mise en clusters par la colonne customer_id. Les données sont organisées dans l'ensemble de blocs suivant :

Identifiant de partition ID de bloc Valeur minimale pour customer_id dans le bloc Valeur maximale pour customer_id dans le bloc
20160501 B1 10000 19999
20160501 B2 20000 24999
20160502 B3 15000 17999
20160501 B4 22000 27999

Vous exécutez la requête suivante sur la table. La requête contient un filtre sur la colonne customer_id.

SELECT
  SUM(totalSale)
FROM
  `mydataset.ClusteredSalesData`
WHERE
  customer_id BETWEEN 20000
  AND 23000
  AND DATE(timestamp) = "2016-05-01"

Cette requête :

  • analyse les colonnes timestamp, customer_id et totalSale dans les blocs B2 et B4 ;
  • élimine le bloc B3 en raison du prédicat de filtre DATE(timestamp) = "2016-05-01" sur la colonne de partitionnement timestamp ;
  • élimine le bloc B1 en raison du prédicat de filtre customer_id BETWEEN 20000 AND 23000 sur la colonne de clustering customer_id.

Interroger des formats en colonnes dans Cloud Storage

Si vos données externes sont stockées aux formats de type ORC ou Parquet, le nombre d'octets facturés est limité aux colonnes lues par BigQuery. Les types de données d'une source de données externe étant convertis en types de données BigQuery par la requête, le nombre d'octets lus est calculé en fonction de la taille des types de données BigQuery. Pour en savoir plus sur les conversions de types de données, consultez les pages suivantes :