Utiliser les résultats de requête mis en cache

BigQuery écrit tous les résultats de requête dans une table. Il s'agit soit d'une table explicitement identifiée par l'utilisateur (une table de destination), soit d'une table temporaire de résultats mis en cache. Si vous exécutez à nouveau la même requête, BigQuery renvoie les résultats depuis la table mise en cache, si elle existe. Les tables temporaires de résultats mis en cache sont gérées par utilisateur et par projet. Selon votre édition, vous pouvez avoir accès aux résultats mis en cache d'autres utilisateurs exécutant des requêtes dans le même projet. Il n'y a aucun coût de stockage pour les tables de résultats de requête mis en cache, mais si vous écrivez des résultats de requête dans une table permanente, le stockage des données vous est facturé.

Tous les résultats de requête, y compris ceux des requêtes interactives et par lots, sont mis en cache dans des tables temporaires pendant environ 24 heures, à quelques exceptions près.

Limites

L'utilisation du cache de requêtes est soumise aux limites suivantes :

  • Lorsque vous exécutez une requête en double, BigQuery tente de réutiliser les résultats mis en cache. Pour récupérer des données du cache, le texte de la requête en double doit être identique à celui de la requête d'origine.
  • Pour que les résultats de requête persistent dans une table de résultats mis en cache, l'ensemble de résultats doit être inférieur à la taille de réponse maximale. Pour plus d'informations sur la gestion d'ensembles de résultats volumineux, consultez la section sur le renvoi des résultats de requête volumineux.
  • Vous ne pouvez pas cibler de tables de résultats mis en cache avec des instructions LMD.
  • Bien que la sémantique actuelle le permette, l'utilisation de résultats mis en cache en entrée pour les tâches dépendantes est déconseillée. Par exemple, vous ne devez pas soumettre de tâches de requête qui extraient les résultats de la table de cache. À la place, écrivez vos résultats dans une table de destination nommée. Pour faciliter le nettoyage, des fonctionnalités peuvent faire expirer automatiquement les données après une certaine durée. C'est le cas, par exemple, de la propriété defaultTableExpirationMs au niveau des ensembles de données.

Tarifs et quotas

Les résultats de requête mis en cache sont stockés sous forme de tables temporaires. Le stockage des résultats de requête mis en cache dans des tables temporaires ne vous est pas facturé. Lorsque les résultats de requête sont extraits d'une table de résultats mis en cache, la propriété statistics.query.cacheHit des statistiques de job renvoie la valeur true, et la requête n'est pas facturée. Bien que les requêtes qui utilisent des résultats mis en cache ne soient pas payantes, elles restent soumises aux règles de quotas de BigQuery. Permettant non seulement de réduire les coûts, ce type de requête est aussi beaucoup plus rapide, car BigQuery n'a pas besoin de calculer l'ensemble de résultats.

Exceptions à la mise en cache des requêtes

Les résultats de requête ne sont pas mis en cache :

  • lorsqu'une table de destination est spécifiée dans la configuration de job, la console Google Cloud, l'outil de ligne de commande bq ou l'API ;
  • si l'une des tables référencées ou des vues logiques a changé depuis la dernière mise en cache des résultats ;
  • lorsque des tables référencées par la requête ont récemment reçu des insertions en flux continu (la table contient des données dans le stockage optimisé en écriture), même si aucune nouvelle ligne n'est arrivée ;
  • si la requête utilise des fonctions non déterministes (par exemple, les fonctions de date et heure, telles que CURRENT_TIMESTAMP() et CURRENT_DATE, ainsi que d'autres fonctions comme SESSION_USER(), elle renvoie des valeurs différentes selon le moment où une requête est exécutée) ;
  • si vous interrogez plusieurs tables à l'aide d'un caractère générique ;
  • si les résultats mis en cache ont expiré (la durée de vie du cache est de 24 heures en général, mais les résultats mis en cache sont les meilleurs possible et peuvent être annulés plus tôt) ;
  • si la requête s'exécute sur une source de données externe autre que Cloud Storage (Les requêtes GoogleSQL sur Cloud Storage sont compatibles avec les résultats de requête mis en cache.)
  • Si la requête s'exécute sur une table protégée par la sécurité au niveau des colonnes, les résultats peuvent ne pas être mis en cache.
  • Si la requête s'exécute sur une table protégée par la sécurité au niveau des lignes, les résultats ne sont pas mis en cache.

Stocker les résultats mis en cache

Lorsque vous exécutez une requête, une table temporaire de résultats mis en cache est créée dans un type spécial d'ensemble de données masqué appelé ensemble de données anonyme. Contrairement aux ensembles de données standards qui héritent des autorisations du modèle de hiérarchie des ressources IAM (autorisations de projet et d'organisation), les ensembles de données anonymes ne sont accessibles que par leur propriétaire. Le propriétaire d'un ensemble de données anonyme correspond à l'utilisateur qui a exécuté la requête ayant généré le résultat mis en cache. De plus, l'autorisation bigquery.jobs.create est vérifiée sur le projet pour s'assurer que l'utilisateur a accès au projet.

BigQuery ne permet pas le partage d'ensembles de données anonymes. Si vous avez l'intention de partager les résultats de requête, n'utilisez pas les résultats mis en cache qui sont stockés dans un ensemble de données anonyme. Il est préférable d'écrire les résultats dans une table de destination nommée.

Bien que l'utilisateur qui exécute la requête dispose d'un accès complet à l'ensemble de données et à la table de résultats mis en cache, il est déconseillé de les utiliser en entrée pour des jobs dépendants.

Les noms des ensembles de données anonymes commencent par un trait de soulignement. Ils sont alors masqués dans la liste des ensembles de données de la console Google Cloud. Vous pouvez répertorier les ensembles de données anonymes et auditer le contrôle d'accès à ces ensembles de données à l'aide de l'outil de ligne de commande bq ou de l'API.

Pour savoir comment répertorier et obtenir des informations sur les ensembles de données, y compris les ensembles de données anonymes, consultez la page Répertorier les ensembles de données.

Mise en cache entre plusieurs utilisateurs

Si vous utilisez une édition Enterprise ou Enterprise Plus et que vous disposez des autorisations nécessaires pour exécuter une requête mise en cache dans votre projet pour un autre utilisateur, BigQuery génère le résultat mis en cache. Le résultat mis en cache est copié dans votre ensemble de données personnel anonyme et reste disponible pendant 24 heures à compter de l'exécution de la requête. Les mêmes limites et exceptions s'appliquent à la mise en cache pour un utilisateur unique.

Désactiver la récupération des résultats mis en cache

L'option Utiliser les résultats mis en cache permet de réutiliser les résultats d'une exécution précédente de la même requête, sauf si les tables interrogées ont été modifiées. L'utilisation des résultats mis en cache n'est utile que pour les requêtes répétées. Bien qu'elle soit activée par défaut, l'option Utiliser les résultats mis en cache n'a aucun effet sur les nouvelles requêtes.

Lorsque vous répétez une requête avec l'option Utiliser les résultats mis en cache désactivée, le résultat mis en cache existant est écrasé. Pour cela, BigQuery doit calculer le résultat de la requête, et le coût de la requête vous est facturé. Ceci est particulièrement utile dans les cas d'analyse comparative.

Si vous souhaitez désactiver la récupération des résultats mis en cache et forcer l'évaluation en direct d'une tâche de requête, vous pouvez définir la propriété configuration.query.useQueryCache de votre tâche de requête sur false.

Pour désactiver l'option Utiliser les résultats mis en cache, procédez comme suit :

Console

  1. Ouvrez Google Cloud Console.
    Accéder à la page BigQuery

  2. Cliquez sur Saisir une nouvelle requête.

  3. Saisissez une requête SQL valide dans la zone de texte de l'éditeur de requête.

  4. Cliquez sur Plus et sélectionnez Paramètres de requête.

    Paramètres de requête

  5. Sous Préférence pour le cache, désactivez l'option Utiliser les résultats mis en cache.

bq

Remplacez le cache de la requête à l'aide du paramètre nouse_cache. Dans l'exemple suivant, BigQuery est obligé de traiter la requête sans utiliser les résultats mis en cache existants :

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

API

Pour traiter une requête sans utiliser les résultats mis en cache, définissez la propriété useQueryCache sur false lorsque vous créez une classe query.

Go

Avant d'essayer cet exemple, suivez les instructions de configuration pour Go du 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 pour Go.

Pour vous authentifier auprès de BigQuery, configurez le service Identifiants par défaut de l'application. Pour en savoir plus, consultez la page Configurer l'authentification pour les bibliothèques clientes.

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

Pour traiter une requête sans utiliser les résultats mis en cache, définissez la propriété UseQueryCache sur false lorsque vous créez une classe QueryJobConfiguration.

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

Avant d'essayer cet exemple, suivez les instructions de configuration pour Node.js du 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 pour Node.js.

Pour vous authentifier auprès de BigQuery, configurez le service Identifiants par défaut de l'application. Pour en savoir plus, consultez la page Configurer l'authentification pour les bibliothèques clientes.

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

Avant d'essayer cet exemple, suivez les instructions de configuration pour PHP du 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 pour PHP.

Pour vous authentifier auprès de BigQuery, configurez le service Identifiants par défaut de l'application. Pour en savoir plus, consultez la page Configurer l'authentification pour les bibliothèques clientes.

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

Avant d'essayer cet exemple, suivez les instructions de configuration pour Python du 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 pour Python.

Pour vous authentifier auprès de BigQuery, configurez le service Identifiants par défaut de l'application. Pour en savoir plus, consultez la page Configurer l'authentification pour les bibliothèques clientes.

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)

Assurer l'utilisation du cache

Lorsque vous utilisez la méthode jobs.insert pour exécuter une requête, vous pouvez forcer l'échec d'une tâche de requête si les résultats mis en cache ne peuvent pas être utilisés. Pour ce faire, définissez la propriété createDisposition de la configuration de tâche query sur CREATE_NEVER.

Si le résultat de la requête n'existe pas dans le cache, une erreur NOT_FOUND est renvoyée.

bq

Utilisez l'option --require_cache pour exiger des résultats du cache de requêtes. Dans l'exemple suivant, BigQuery est obligé de traiter la requête si ses résultats existent dans le 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

Pour traiter une requête avec des résultats mis en cache, définissez la propriété createDisposition sur CREATE_NEVER dans la configuration de la tâche query.

Vérifier l'utilisation du cache

Il existe deux façons de déterminer si BigQuery a renvoyé un résultat à l'aide du cache :

  • Utiliser la console Google Cloud. Accédez aux résultats de requête, puis cliquez sur Informations sur la tâche. Le nombre d'octets traités indique les valeurs 0 o (résultats mis en cache).
  • Utiliser l'API BigQuery. La propriété cacheHit du résultat de la requête est définie sur true.

Impact de la sécurité au niveau des colonnes

Par défaut, BigQuery met en cache les résultats de requête pour une durée de 24 heures, sauf dans le cas des exceptions mentionnées précédemment. Les requêtes portant sur une table protégée par la sécurité au niveau des colonnes peuvent ne pas être mises en cache. Si BigQuery met en cache les résultats, la durée de vie du cache de 24 heures s'applique.

Une modification telle que la suppression d'un groupe ou d'un utilisateur du rôle Lecteur détaillé Data Catalog utilisé pour un tag avec stratégie n'annule pas le cache de 24 heures. Une modification apportée au groupe de contrôle d'accès Lecteur détaillé Data Catalog est appliquée immédiatement au groupe proprement dit, mais la modification n'annule pas le cache.

Ceci implique que, pour tout utilisateur ayant exécuté une requête, les résultats de cette requête restent visibles à l'écran. L'utilisateur peut également continuer à récupérer ces résultats à partir du cache, même s'il a perdu l'accès aux données au cours des dernières 24 heures.

Au cours des 24 heures suivant la suppression d'un utilisateur du rôle Lecteur détaillé Data Catalog associé à un tag avec stratégie, cet utilisateur peut toujours accédér aux données mises en cache qu'il était auparavant autorisé à consulter. Si des lignes sont ajoutées à la table, l'utilisateur ne peut pas les voir, même si les résultats sont mis en cache.