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
ouDELETE
- 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 :
- 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. - Si
chosen
est présent dans les statistiques et que sa valeur estTRUE
, la vue matérialisée est utilisée par la requête. - 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
- 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. - Consultez la
rejected_reason
pour connaître les étapes suivantes. Par exemple, si la valeurrejected_reason
estCOST
, le réglage intelligent a identifié des sources de données plus efficaces en termes de coût et de performances. - 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.
- 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
SELECT * FROM my_dataset.my_materialized_table LIMIT 10
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'
SELECT SUM(total_paid) FROM my_dataset.my_materialized_table WHERE date > '2020-12-01'