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. Les tables temporaires de résultats mis en cache sont gérées par utilisateur et par projet. Il n'y a aucun coût de stockage pour les tables temporaires, 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 vivement 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

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 tâche 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 la tâche, Cloud Console, 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 (un tampon de diffusion en continu est associé à la table), 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 NOW(), ainsi que d'autres fonctions comme CURRENT_USER(), renvoient 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.

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 ensemble de données spécial 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.

Lorsqu'un ensemble de données anonyme est créé, un accès bigquery.dataOwner à ce dernier est accordé de façon explicite à l'utilisateur qui exécute la tâche de requête. L'accès bigquery.dataOwner n'attribue un contrôle total sur l'ensemble de données qu'à l'utilisateur ayant exécuté la tâche de requête. Il permet entre autres de contrôler entièrement les tables de résultats mises en cache dans l'ensemble de données anonyme. 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 fortement déconseillé de les utiliser en entrée pour des tâches dépendantes.

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 Cloud Console. 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.

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 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 en matière de cache, décochez l'option Utiliser les résultats mis en cache.

    Option d'utilisation des 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 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"
	"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 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');

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));
}

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 Python.

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 exécutez une requête à l'aide de la fonction jobs.insert, 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 la tâche copy sur CREATE_NEVER.

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

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 :

  • Si vous utilisez Cloud Console, la chaîne de résultat ne contient pas d'informations sur le nombre d'octets traités et affiche le mot cached.

    Indicateur de cache dans Cloud Console.

  • Si vous utilisez 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. La mise en cache de 24 heures s'applique également aux requêtes effectuées sur des données protégées par la sécurité au niveau des colonnes, qui utilise des tags avec stratégie. 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 les verra pas, même si les résultats sont mis en cache.