Utiliser les vues matérialisées

Ce document fournit des informations supplémentaires sur les vues matérialisées et leur utilisation. Avant de lire ce document, consultez les pages Présentation des vues matérialisées et Créer des vues matérialisées.

Interroger les vues matérialisées

Vous pouvez interroger directement vos vues matérialisées de la même manière que vous interrogez une table ou une vue standard. Les requêtes sur les vues matérialisées sont toujours cohérentes avec les requêtes sur les tables de base de la vue, même si celles-ci ont été modifiées depuis la dernière actualisation de la vue matérialisée. Les requêtes ne déclenchent pas automatiquement une actualisation de la vue matérialisée.

Rôles requis

Pour obtenir les autorisations nécessaires pour interroger une vue matérialisée, demandez à votre administrateur de vous accorder le rôle IAM Lecteur de données BigQuery (roles/bigquery.dataViewer) sur la table de base de la vue matérialisée et la vue matérialisée elle-même. Pour en savoir plus sur l'attribution de rôles, consultez la section Gérer les accès.

Ce rôle prédéfini contient les autorisations requises pour interroger une vue matérialisée. Pour connaître les autorisations exactes requises, développez la section Autorisations requises :

Autorisations requises

Vous devez disposer des autorisations suivantes pour interroger une vue matérialisée :

  • bigquery.tables.get
  • bigquery.tables.getData

Vous pouvez également obtenir ces autorisations avec des rôles personnalisés ou d'autres rôles prédéfinis.

Ces autorisations sont requises pour les requêtes afin de pouvoir bénéficier du réglage intelligent.

Pour en savoir plus sur les rôles IAM dans BigQuery, consultez la page Présentation d'IAM.

Mises à jour incrémentielles

BigQuery combine les données de la vue mise en cache avec de nouvelles données pour fournir des résultats de requête cohérents tout en utilisant la vue matérialisée. Pour les vues matérialisées à table unique, cela est possible lorsque la table de base n'a pas changé depuis la dernière actualisation ou lorsque de nouvelles données ont été ajoutées. Pour les vues JOIN, seules les tables situées à gauche de JOIN peuvent contenir des données ajoutées. Si l'une des tables situées à droite d'un élément JOIN a été modifiée, la vue ne peut pas être mise à jour de manière incrémentielle.

Si la table de base a été mise à jour ou supprimée depuis la dernière actualisation, ou si les tables de base de la vue matérialisée à droite de JOIN ont été modifiées, BigQuery rétablit automatiquement la requête d'origine. Pour en savoir plus sur les jointures et les vues matérialisées, consultez la page Jointures. Voici des exemples de la console Google Cloud, de l'outil de ligne de commande bq et des actions d'API qui peuvent entraîner une mise à jour ou une suppression :

  • Instructions LMD (langage de manipulation de données)UPDATE, MERGE ou DELETE
  • Troncation
  • Expiration de la partition

Les opérations de métadonnées suivantes empêchent également la mise à jour incrémentielle d'une vue matérialisée :

  • Modifier l'expiration de la partition
  • Mettre à jour ou supprimer une colonne

Si une vue matérialisée ne peut pas être mise à jour de manière incrémentielle, ses données mises en cache ne sont pas utilisées par les requêtes tant que la vue n'est pas actualisée automatiquement ou manuellement. Pour savoir pourquoi une tâche n'a pas utilisé de données de vues matérialisées, consultez Comprendre pourquoi les vues matérialisées ont été refusées.

Alignement des partitions

Si une vue matérialisée est partitionnée, BigQuery s'assure que ses partitions sont alignées sur les partitions de la colonne de partitionnement de la table de base. Alignée signifie que les données d'une partition particulière de la table de base contribuent à la même partition de la vue matérialisée. Par exemple, une ligne de la partition 20220101 de la table de base ne contribuerait qu'à la partition 20220101 de la vue matérialisée.

Lorsqu'une vue matérialisée est partitionnée, le comportement décrit dans les mises à jour incrémentielles se produit pour chaque partition individuelle. Par exemple, si des données sont supprimées dans une partition de la table de base, BigQuery peut toujours utiliser les autres partitions de la vue matérialisée.

Les vues matérialisées comportant des jointures internes ne peuvent être alignées qu'avec l'une de leurs tables de base. Si l'une des tables de base non alignées change, elle affecte l'intégralité de la vue.

Réglage intelligent

Dans la mesure du possible, BigQuery réécrit automatiquement les requêtes de sorte qu'elles utilisent des vues matérialisées. La réécriture automatique améliore les performances et les coûts des requêtes, et ne modifie pas les résultats des requêtes. Les requêtes ne déclenchent pas automatiquement une actualisation de la vue matérialisée. Pour qu'une requête soit réécrite, la vue matérialisée doit répondre aux conditions suivantes :

  • appartenir au même ensemble de données que l'une de ses tables de base ;
  • utiliser le même ensemble de tables de base que la requête ;
  • inclure toutes les colonnes en cours de lecture ;
  • inclure toutes les lignes en cours de lecture.

Exemples de réglages intelligents

Prenons l'exemple de requête de vue matérialisée suivant :

SELECT
  store_id,
  CAST(sold_datetime AS DATE) AS sold_date
  SUM(net_profit) AS sum_profit
FROM dataset.store_sales
WHERE
  CAST(sold_datetime AS DATE) >= '2021-01-01' AND
  promo_id IS NOT NULL
GROUP BY 1, 2

Les exemples suivants illustrent les requêtes et expliquent pourquoi ces requêtes sont ou non réécrites automatiquement à l'aide de cette vue :

Query Réécriture ? Motif
SELECT
SUM(net_paid) AS sum_paid,
SUM(net_profit) AS sum_profit
FROM dataset.store_sales
WHERE
CAST(sold_datetime AS DATE) >= '2021-01-01' AND
promo_id IS NOT NULL
Non La vue doit inclure toutes les colonnes en cours de lecture. La vue n'inclut pas "SUM(net_paid)".
SELECT SUM(net_profit) AS sum_profit
FROM dataset.store_sales
WHERE
CAST(sold_datetime AS DATE) >= '2021-01-01' AND
promo_id IS NOT NULL
Yes
SELECT SUM(net_profit) AS sum_profit
FROM dataset.store_sales
WHERE
CAST(sold_datetime AS DATE) >= '2021-01-01' AND
promo_id IS NOT NULL AND
customer_id = 12345
Non La vue doit inclure toutes les colonnes en cours de lecture. La vue n'inclut pas "customer".
SELECT SUM(net_profit) AS sum_profit
FROM dataset.store_sales
WHERE
sold_datetime= '2021-01-01' AND
promo_id IS NOT NULL
Non La vue doit inclure toutes les colonnes en cours de lecture. "retail_datetime" n'est pas une sortie, mais "CAST(sold_datetime AS DATE)" en est une.
SELECT SUM(net_profit) AS sum_profit
FROM dataset.store_sales
WHERE
CAST(sold_datetime AS DATE) >= '2021-01-01' AND
promo_id IS NOT NULL AND
store_id = 12345
Oui
SELECT SUM(net_profit) AS sum_profit
FROM dataset.store_sales
WHERE
CAST(sold_datetime AS DATE) >= '2021-01-01' AND
promo_id = 12345
Non La vue doit inclure toutes les lignes en cours de lecture. "promo_id" n'est pas un résultat. Vous ne pouvez donc pas appliquer le filtre plus restrictif à la vue.
SELECT SUM(net_profit) AS sum_profit
FROM dataset.store_sales
WHERE CAST(sold_datetime AS DATE) >= '2020-01-01'
Non La vue doit inclure toutes les lignes en cours de lecture. La vue filtre les dates pour n'afficher que celles en 2021 et ultérieures, mais la requête lit les dates de 2020.
SELECT SUM(net_profit) AS sum_profit
FROM dataset.store_sales
WHERE
CAST(sold_datetime AS DATE) >= '2022-01-01' AND
promo_id IS NOT NULL
Yes

Déterminer si une requête a été réécrite

Pour savoir si une requête a été réécrite par un réglage intelligent pour utiliser une vue matérialisée, inspectez le plan de requête. Si la requête a été réécrite, le plan de requête contient une étape READ my_materialized_view, dans laquelle my_materialized_view est le nom de la vue matérialisée utilisée. Pour comprendre pourquoi une requête n'a pas utilisé de vue matérialisée, consultez la section Comprendre pourquoi des vues matérialisées ont été refusées.

Comprendre pourquoi des vues matérialisées ont été refusées

Les requêtes ne peuvent pas utiliser une vue matérialisée pour diverses raisons. La procédure à suivre pour comprendre pourquoi une vue matérialisée a été rejetée dépend du type de requête que vous avez utilisé :

  • Requête directe sur la vue matérialisée
  • Requête indirecte dans laquelle le réglage intelligent peut choisir d'utiliser la vue matérialisée

Les sections suivantes vous aident à comprendre pourquoi une vue matérialisée a été refusée.

Requête directe sur les vues matérialisées

Les requêtes directes sur des vues matérialisées peuvent ne pas utiliser de données mises en cache dans certains cas. Les étapes suivantes peuvent vous aider à comprendre pourquoi les données de vues matérialisées n'ont pas été utilisées :

  1. Suivez les étapes de la section Surveiller l'utilisation de la vue matérialisée et recherchez la vue matérialisée cible dans le champ materialized_view_statistics de la requête.
  2. Si chosen est présent dans les statistiques et que sa valeur est TRUE, la vue matérialisée est utilisée par la requête.
  3. Consultez le champ rejected_reason pour connaître les étapes suivantes. Dans la plupart des cas, vous pouvez actualiser manuellement la vue matérialisée ou attendre la prochaine actualisation automatique.

Requête avec réglage intelligent

  1. Suivez les étapes de la section Surveiller l'utilisation de la vue matérialisée et recherchez la vue matérialisée cible dans materialized_view_statistics pour la requête.
  2. Consultez la rejected_reason pour connaître les étapes suivantes. Par exemple, si la valeur rejected_reason est COST, le réglage intelligent a identifié des sources de données plus efficaces en termes de coût et de performances.
  3. Si la vue matérialisée n'est pas présente, essayez une requête directe sur la vue matérialisée et suivez les étapes décrites dans la section Requête directe sur des vues matérialisées.
  4. Si la requête directe n'utilise pas la vue matérialisée, la forme de la vue matérialisée ne correspond pas à la requête. Pour plus d'informations sur le réglage intelligent et la réécriture des requêtes à l'aide de vues matérialisées, consultez la section Exemples de réglage intelligent.

Questions fréquentes

Quand dois-je utiliser les requêtes programmées plutôt que les vues matérialisées ?

Les requêtes programmées constituent un moyen pratique d'exécuter régulièrement des calculs arbitrairement complexes. À chacune de ses exécutions, une requête est exécutée dans son intégralité. Les résultats précédents ne sont pas utilisés, et vous assumez entièrement le coût de la requête. Les requêtes programmées sont particulièrement utiles lorsque vous n'avez pas besoin d'obtenir les données les plus récentes et pouvez vous permettre une grande tolérance en termes d'obsolescence des données.

L'utilisation des vues matérialisées se justifie lorsque vous devez interroger les données les plus récentes tout en réduisant la latence et les coûts par réutilisation des résultats précédemment calculés. Vous pouvez utiliser les vues matérialisées en tant que pseudo-index, ce qui vous permet d'accélérer les requêtes adressées à la table de base sans mettre à jour les workflows existants. L'option --max_staleness vous permet de définir une obsolescence acceptable pour les vues matérialisées, ce qui offre des performances élevées et cohérentes avec des coûts contrôlés lors du traitement d'ensembles de données qui changent fréquemment.

De manière générale, dans la mesure du possible et si vous n'exécutez pas de calculs arbitrairement complexes, utilisez les vues matérialisées.

Certaines requêtes sur les vues matérialisées sont plus lentes que les mêmes requêtes portant sur des tables matérialisées manuellement. Pourquoi ?

En général, une requête sur une vue matérialisée n'est pas toujours aussi performante qu'une requête sur la table matérialisée équivalente. En effet, une vue matérialisée garantit toujours le renvoi d'un résultat actualisé, ce qui suppose de tenir compte des modifications apportées aux tables de base depuis la dernière actualisation de la vue.

Étudions le scénario suivant :

CREATE MATERIALIZED VIEW my_dataset.my_mv AS
SELECT date, customer_id, region, SUM(net_paid) as total_paid
FROM my_dataset.sales
GROUP BY 1, 2, 3;

CREATE TABLE my_dataset.my_materialized_table AS
SELECT date, customer_id, region, SUM(net_paid) as total_paid
FROM my_dataset.sales
GROUP BY 1, 2, 3;

Par exemple, la requête suivante :

  SELECT * FROM my_dataset.my_mv LIMIT 10
s'exécute généralement beaucoup plus lentement que cette requête :
  SELECT * FROM my_dataset.my_materialized_table LIMIT 10
Pour fournir des résultats à jour de manière cohérente, BigQuery doit interroger les nouvelles lignes de la table de base et les fusionner dans la vue matérialisée avant d'appliquer le prédicat "LIMIT 10". Par conséquent, le chargement est lent, même si la vue matérialisée est à jour.

En revanche, les agrégations sur les vues matérialisées sont généralement aussi rapides que les requêtes sur la table matérialisée. Par exemple, cette agrégation :

  SELECT SUM(total_paid) FROM my_dataset.my_mv WHERE date > '2020-12-01'
Doit être aussi rapide que cette requête :
  SELECT SUM(total_paid) FROM my_dataset.my_materialized_table WHERE date > '2020-12-01'