Usar resultados de consultas almacenados en caché

BigQuery escribe todos los resultados de las consultas en una tabla. El usuario identifica explícitamente la tabla (una tabla de destino) o se trata de una tabla temporal de resultados almacenados en caché. Si vuelves a ejecutar la misma consulta, BigQuery devolverá los resultados de la tabla almacenada en caché, si existe. Las tablas de resultados temporales almacenados en caché se mantienen por usuario y por proyecto. En función de tu edición, es posible que tengas acceso a resultados almacenados en caché de otros usuarios que ejecuten consultas en el mismo proyecto. No se aplican costes de almacenamiento a las tablas de resultados de consultas almacenadas en caché, pero si escribes los resultados de una consulta en una tabla permanente, se te cobrará por almacenar los datos.

Todos los resultados de las consultas, incluidas las consultas interactivas y por lotes, se almacenan en caché en tablas temporales durante aproximadamente 24 horas, con algunas excepciones.

Limitaciones

El uso de la caché de consultas está sujeto a las siguientes limitaciones:

  • Cuando ejecutas una consulta duplicada, BigQuery intenta reutilizar los resultados almacenados en caché. Para recuperar datos de la caché, el texto de la consulta duplicada debe ser el mismo que el de la consulta original.
  • Para que los resultados de las consultas se conserven en una tabla de resultados almacenados en caché, el conjunto de resultados debe ser inferior al tamaño máximo de respuesta. Para obtener más información sobre cómo gestionar conjuntos de resultados de gran volumen, consulta el artículo Devolver resultados de consultas de gran volumen.
  • No puedes orientar las tablas de resultados almacenados en caché con instrucciones DML.
  • Aunque la semántica actual lo permite, no se recomienda usar resultados almacenados en caché como entrada para trabajos dependientes. Por ejemplo, no debes enviar trabajos de consulta que obtengan resultados de la tabla de caché. En su lugar, escribe los resultados en una tabla de destino con nombre. Para simplificar la limpieza, las funciones como la propiedad defaultTableExpirationMs a nivel de conjunto de datos pueden hacer que los datos caduquen automáticamente después de un periodo determinado.

Precios y cuotas

Los resultados de las consultas almacenados en caché se guardan como tablas temporales. No se te cobrará por el almacenamiento de los resultados de las consultas almacenados en caché en tablas temporales. Cuando los resultados de una consulta se obtienen de una tabla de resultados almacenados en caché, la propiedad de estadísticas de trabajo statistics.query.cacheHit devuelve el valor true y no se te cobra por la consulta. Aunque no se te cobra por las consultas que usan resultados almacenados en caché, estas están sujetas a las políticas de cuotas de BigQuery. Además de reducir los costes, las consultas que usan resultados almacenados en caché son mucho más rápidas porque BigQuery no tiene que calcular el conjunto de resultados.

Excepciones al almacenamiento en caché de consultas

Los resultados de las consultas no se almacenan en caché:

  • Cuando se especifica una tabla de destino en la configuración de la tarea, la Google Cloud consola, la herramienta de línea de comandos bq o la API.
  • Si alguna de las tablas o vistas lógicas a las que se hace referencia ha cambiado desde que se almacenaron en caché los resultados.
  • Cuando alguna de las tablas a las que hace referencia la consulta ha recibido recientemente inserciones de streaming (la tabla tiene datos en el almacenamiento optimizado para escritura), aunque no hayan llegado filas nuevas.
  • Si la consulta usa funciones no deterministas, como funciones de fecha y hora (por ejemplo, CURRENT_TIMESTAMP() y CURRENT_DATE) y otras funciones (como SESSION_USER()), devuelve valores diferentes en función de cuándo se ejecute la consulta.
  • Si consultas varias tablas con un comodín.
  • Si los resultados almacenados en caché han caducado. La duración típica de la caché es de 24 horas, pero los resultados almacenados en caché se ofrecen de la mejor forma posible y pueden invalidarse antes.
  • Si la consulta se ejecuta en una fuente de datos externa que no sea Cloud Storage. Las consultas de GoogleSQL en Cloud Storage se admiten mediante resultados de consultas almacenados en caché.
  • Si la consulta se ejecuta en una tabla protegida por seguridad a nivel de fila, los resultados no se almacenan en caché.
  • Si la consulta se ejecuta en una tabla protegida por seguridad a nivel de columna, es posible que los resultados no se almacenen en caché.
  • Si el texto de la consulta ha cambiado de alguna forma, incluidos los espacios en blanco o los comentarios modificados.

Cómo se almacenan los resultados almacenados en caché

Cuando ejecuta una consulta, se crea una tabla de resultados temporales almacenados en caché en un tipo especial de conjunto de datos oculto denominado conjunto de datos anónimo. A diferencia de los conjuntos de datos normales, que heredan los permisos del modelo de jerarquía de recursos de gestión de identidades y accesos (permisos de proyecto y de organización), el acceso a los conjuntos de datos anónimos está restringido al propietario. El propietario de un conjunto de datos anónimo es el usuario que ejecutó la consulta que produjo el resultado almacenado en caché. Además, se comprueba el permiso bigquery.jobs.create en el proyecto para verificar que el usuario tiene acceso a él.

BigQuery no permite compartir conjuntos de datos anónimos. Si tienes intención de compartir los resultados de una consulta, no utilices los resultados almacenados en caché en un conjunto de datos anónimo. En su lugar, escribe los resultados en una tabla de destino con nombre.

Aunque el usuario que ejecuta la consulta tiene acceso completo al conjunto de datos y a la tabla de resultados almacenados en caché, no se recomienda usarlos como entradas para trabajos dependientes.

Los nombres de los conjuntos de datos anónimos empiezan por un guion bajo. De esta forma, no aparecerán en la lista de conjuntos de datos de la consola Google Cloud . Puedes enumerar los conjuntos de datos anónimos y auditar los controles de acceso a conjuntos de datos anónimos mediante la herramienta de línea de comandos bq o la API.

Para obtener más información sobre cómo mostrar y obtener información sobre conjuntos de datos, incluidos los anónimos, consulta el artículo Mostrar conjuntos de datos.

Almacenamiento en caché entre usuarios

Si usas la edición Enterprise o Enterprise Plus y tienes los permisos necesarios para ejecutar una consulta almacenada en caché en tu proyecto para otro usuario, BigQuery generará el resultado almacenado en caché. El resultado almacenado en caché se copia en tu conjunto de datos anónimo personal y permanece ahí durante 24 horas desde que ejecutaste la consulta. Los mismos límites y excepciones para el almacenamiento en caché de un solo usuario se aplican al almacenamiento en caché entre usuarios.

Inhabilitar la recuperación de resultados almacenados en caché

La opción Usar los resultados almacenados en caché reutiliza los resultados de una ejecución anterior de la misma consulta, a menos que las tablas consultadas hayan cambiado. Usar resultados almacenados en caché solo es útil para consultas repetidas. En las consultas nuevas, la opción Usar resultados en caché no tiene ningún efecto, aunque está habilitada de forma predeterminada.

Si repites una consulta con la opción Utilizar los resultados almacenados en caché inhabilitada, se sobrescribirá el resultado almacenado en caché. Para ello, BigQuery debe calcular el resultado de la consulta, por lo que se te cobrará por ella. Esto resulta especialmente útil en las comparativas.

Si quieres inhabilitar la recuperación de resultados almacenados en caché y forzar la evaluación en tiempo real de una tarea de consulta, puedes asignar el valor false a la propiedad configuration.query.useQueryCache de la tarea de consulta.

Para inhabilitar la opción Usar resultados almacenados en caché, sigue estos pasos:

Consola

  1. Abre la Google Cloud consola.
    Ve a la página de BigQuery

  2. Haz clic en Redactar nueva consulta.

  3. Introduce una consulta de SQL válida en el área de texto Editor de consultas.

  4. Haz clic en Más y selecciona Configuración de la consulta.

    Configuración de consultas

  5. En Preferencia de caché, desmarca Usar resultados almacenados en caché.

bq

Usa la marca nouse_cache para sobrescribir la caché de consultas. En el siguiente ejemplo, se obliga a BigQuery a procesar la consulta sin usar los resultados almacenados en caché:

 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 procesar una consulta sin usar los resultados almacenados en caché, asigna el valor false a la propiedad useQueryCache en la configuración de la tarea query.

Go

Antes de probar este ejemplo, sigue las Goinstrucciones de configuración de la guía de inicio rápido de BigQuery con bibliotecas de cliente. Para obtener más información, consulta la documentación de referencia de la API Go de BigQuery.

Para autenticarte en BigQuery, configura las credenciales predeterminadas de la aplicación. Para obtener más información, consulta el artículo Configurar la autenticación 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 procesar una consulta sin usar los resultados almacenados en caché, define useQueryCache como false al crear un QueryJobConfiguration.

Antes de probar este ejemplo, sigue las Javainstrucciones de configuración de la guía de inicio rápido de BigQuery con bibliotecas de cliente. Para obtener más información, consulta la documentación de referencia de la API Java de BigQuery.

Para autenticarte en BigQuery, configura las credenciales predeterminadas de la aplicación. Para obtener más información, consulta el artículo Configurar la autenticación para bibliotecas de cliente.

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 probar este ejemplo, sigue las Node.jsinstrucciones de configuración de la guía de inicio rápido de BigQuery con bibliotecas de cliente. Para obtener más información, consulta la documentación de referencia de la API Node.js de BigQuery.

Para autenticarte en BigQuery, configura las credenciales predeterminadas de la aplicación. Para obtener más información, consulta el artículo Configurar la autenticación 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 probar este ejemplo, sigue las PHPinstrucciones de configuración de la guía de inicio rápido de BigQuery con bibliotecas de cliente. Para obtener más información, consulta la documentación de referencia de la API PHP de BigQuery.

Para autenticarte en BigQuery, configura las credenciales predeterminadas de la aplicación. Para obtener más información, consulta el artículo Configurar la autenticación 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 probar este ejemplo, sigue las Pythoninstrucciones de configuración de la guía de inicio rápido de BigQuery con bibliotecas de cliente. Para obtener más información, consulta la documentación de referencia de la API Python de BigQuery.

Para autenticarte en BigQuery, configura las credenciales predeterminadas de la aplicación. Para obtener más información, consulta el artículo Configurar la autenticación 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)

Asegurarse de que se usa la caché

Si usas el método jobs.insert para ejecutar una consulta, puedes forzar que una tarea de consulta falle a menos que se puedan usar resultados almacenados en caché. Para ello, define la propiedad createDisposition de la configuración de la tarea query como CREATE_NEVER.

Si el resultado de la consulta no está en la caché, se devuelve un error NOT_FOUND.

bq

Usa la marca --require_cache para requerir resultados de la caché de consultas. En el siguiente ejemplo, se obliga a BigQuery a procesar la consulta si sus resultados están en la caché:

 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 procesar una consulta con resultados almacenados en caché, asigna el valor CREATE_NEVER a la propiedad createDisposition en la configuración de la tarea query.

Verificar el uso de la caché

Usa uno de los siguientes métodos para determinar si BigQuery ha devuelto un resultado mediante la caché:

  • Usa la Google Cloud consola. Ve a Resultados de la consulta y haz clic en Información del trabajo. En Bytes procesados se muestra 0 B (resultados almacenados en caché).
  • Usa la API de BigQuery. La propiedad cacheHit del resultado de la consulta se define como true.

Impacto de la seguridad a nivel de columna

De forma predeterminada, BigQuery almacena en caché los resultados de las consultas durante 24 horas, con las excepciones que se han indicado anteriormente. Es posible que no se almacenen en caché las consultas en una tabla protegida por la seguridad a nivel de columna. Si BigQuery almacena en caché el resultado, se aplica el tiempo de conservación de la caché de 24 horas.

Un cambio como la eliminación de un grupo o un usuario del rol Lector pormenorizado de Data Catalog utilizado en una etiqueta de política no invalida la caché de 24 horas. Un cambio en el propio grupo de control de acceso Lector pormenorizado de Data Catalog se propaga inmediatamente, pero no invalida la caché.

El impacto se produce si un usuario ejecuta una consulta, ya que los resultados de la consulta siguen siendo visibles para el usuario en pantalla. El usuario también puede recuperar esos resultados de la caché aunque haya perdido el acceso a los datos en las últimas 24 horas.

Durante las 24 horas posteriores a que se quite a un usuario del rol Lector pormenorizado de Data Catalog de una etiqueta de política, el usuario solo podrá acceder a los datos almacenados en caché que se le haya permitido ver anteriormente. Si se añaden filas a la tabla, el usuario no puede verlas, aunque los resultados estén en caché.