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 page Gérer l'accès aux projets, aux dossiers et aux organisations.

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

Les mises à jour incrémentielles se produisent lorsque 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 si la table de base n'a pas changé depuis la dernière actualisation ou si de nouvelles données ont été ajoutées. Pour les vues JOIN, seules les tables situées dans la partie gauche d'une vue JOIN peuvent comporter des données ajoutées. Si l'une des tables situées en partie droite d'une vue 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 situées en partie droite de la vue JOIN ont été modifiées, BigQuery n'utilise pas les mises à jour incrémentielles et 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. De plus, les vues matérialisées ne peuvent pas être mises à jour de manière incrémentielle si leur table de base a accumulé des modifications non traitées pendant une période supérieure à l'intervalle de fonctionnalité temporelle de la table.

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 indépendamment 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 sans nécessiter une actualisation complète de l'ensemble 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.

Le réglage intelligent n'est pas compatible avec les éléments suivants:

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 :

Requête 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
Oui
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
Oui

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

Si vous avez désactivé l'actualisation automatique de votre vue matérialisée et que la table comporte des modifications non traitées, la requête sera traitée potentiellement plus rapidement pendant plusieurs jours, mais va ensuite revenir à la requête d'origine, ce qui ralentit le traitement. Pour bénéficier des vues matérialisées, activez l'actualisation automatique, ou procédez à des actualisations manuelles régulières, et surveillez les jobs d'actualisation des vues matérialisées pour vous assurer qu'ils aboutissent.

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. La requête est traitée dans sa totalité à chaque exécution, sans bénéficier des résultats précédents, et vous payez le coût de calcul total de la requête. Les requêtes programmées sont idéales lorsque vous n'avez pas besoin d'obtenir les données les plus récentes et que vous n'êtes que très peu regardant sur le critère d'obsolescence des données.

Les vues matérialisées sont plus adaptées lorsque vous devez interroger les données les plus récentes en bénéficiant d'une latence et de coûts réduits au minimum, en réutilisant des résultats calculés précédemment. Vous pouvez utiliser les vues matérialisées comme des 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 vos vues matérialisées, ce qui offre des performances élevées et cohérentes et une bonne maîtrise des coûts, lors du traitement d'ensembles de données volumineux et sujets à de fréquentes modifications.

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, les vues matérialisées renvoient toujours des résultats actualisés et doivent tenir compte des modifications apportées à leurs 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 actualisés 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'