MaxCompute prend en charge la réécriture des requêtes SQL d'origine pour utiliser une vue matérialisée si les requêtes contiennent des conditions de filtrage ou certains types d'opérateurs.
Remarques sur l'utilisation
Le principe fondamental de la réécriture de requête avec vue matérialisée repose sur le fait que la vue matérialisée doit contenir toutes les données requises par la requête. Cela inclut les colonnes de sortie ainsi que toutes les colonnes utilisées dans les conditions de filtrage, les fonctions d'agrégation ou les conditions de jointure (JOIN). Une requête ne peut pas être réécrite si elle nécessite des colonnes absentes de la vue matérialisée ou si elle utilise une fonction d'agrégation non prise en charge.
-
Pour activer la réécriture de requête avec vue matérialisée, ajoutez la configuration suivante avant votre instruction de requête :
SET odps.sql.materialized.view.enable.auto.rewriting=true;La réécriture de requête n'est pas prise en charge lorsque la vue matérialisée se trouve dans un état invalide. Dans ce cas, la requête s'exécute directement sur la table source sans accélération.
-
Réécriture inter-projets
Par défaut, un projet MaxCompute ne peut utiliser que ses propres vues matérialisées pour la réécriture de requêtes. Pour utiliser des vues matérialisées provenant d'autres projets, spécifiez une liste de projets MaxCompute autorisés en ajoutant la configuration suivante avant votre requête :
SET odps.sql.materialized.view.source.project.white.list = <project_name1>,<project_name2>,<project_name3>; -
Pour activer les réécritures utilisant des vues matérialisées définies avec
LEFT/RIGHT JOINouUNION ALL, ajoutez la configuration suivante avant votre instruction de requête :SET odps.sql.materialized.view.enable.substitute.rewriting=true;
Types d'opérateurs pris en charge
Le tableau suivant compare les types d'opérateurs de réécriture de requête pris en charge par MaxCompute avec ceux d'autres produits.
|
Type d'opérateur |
Classification |
MaxCompute |
BigQuery |
Amazon Redshift |
Hive |
|
FILTER |
Correspondance d'expression complète |
Pris en charge |
Pris en charge |
Pris en charge |
Pris en charge |
|
Correspondance d'expression partielle |
Pris en charge |
Pris en charge |
Pris en charge |
Pris en charge |
|
|
AGGREGATE |
Agrégation unique |
Pris en charge |
Pris en charge |
Pris en charge |
Pris en charge |
|
Agrégations multiples |
Non pris en charge |
Non pris en charge |
Non pris en charge |
Non pris en charge |
|
|
JOIN |
Type de JOIN |
INNER JOIN |
Non pris en charge |
INNER JOIN |
INNER JOIN |
|
JOIN unique |
Pris en charge |
Non pris en charge |
Pris en charge |
Pris en charge |
|
|
JOINs multiples |
Pris en charge |
Non pris en charge |
Pris en charge |
Pris en charge |
|
|
AGGREGATE+JOIN |
- |
Pris en charge |
Non pris en charge |
Pris en charge |
Pris en charge |
Exemples
Exemple 1 : Réécriture avec conditions de filtrage
-
Créez une vue matérialisée.
CREATE MATERIALIZED VIEW mv AS SELECT a,b,c FROM src WHERE a>5; -
Le tableau suivant présente des exemples de réécriture pour la vue matérialisée.
Requête d'origine
Requête réécrite
SELECT a,b FROM src WHERE a>5;SELECT a,b FROM mv;SELECT a, b FROM src WHERE a=10;SELECT a,b FROM mv WHERE a=10;SELECT a, b FROM src WHERE a=10 AND b='3';SELECT a,b FROM mv WHERE a=10 AND b=3;SELECT a, b FROM src WHERE a>3;(SELECT a,b FROM src WHERE a>3 AND a<=5) UNION (SELECT a,b FROM mv);SELECT a, b FROM src WHERE a=10 AND d=4;Échec de la réécriture car la vue matérialisée ne contient pas la colonne
d.SELECT d, e FROM src WHERE a=10;Échec de la réécriture car la vue matérialisée ne contient pas les colonnes
dete.SELECT a, b FROM src WHERE a=1;Échec de la réécriture car la vue matérialisée ne contient pas les données où
a=1.
Exemple 2 : Réécriture avec fonctions d'agrégation
Toutes les fonctions d'agrégation peuvent être réécrites si la vue matérialisée et la requête partagent la même clé d'agrégation. Si les clés d'agrégation diffèrent, seules les réécritures utilisant SUM, MIN et MAX sont prises en charge.
-
Créez une vue matérialisée.
CREATE MATERIALIZED VIEW mv AS SELECT a, b, sum(c) AS sum, count(d) AS cnt FROM src GROUP BY a, b; -
Le tableau suivant illustre la réécriture des requêtes basée sur la vue matérialisée.
Requête d'origine
Requête réécrite
SELECT a, sum(c) FROM src GROUP BY a;SELECT a, sum(sum) FROM mv GROUP BY a;SELECT a, count(d) FROM src GROUP BY a, b;SELECT a, cnt FROM mv;SELECT a, count(b) FROM (SELECT a, b FROM src GROUP BY a, b) GROUP BY a;SELECT a,count(b) FROM mv GROUP BY a;SELECT a,count(b) FROM mv GROUP BY a;Échec de la réécriture car la vue a déjà agrégé les colonnes
aetb, donc la colonnebne peut pas être agrégée à nouveau.SELECT a, count(c) FROM src GROUP BY a;Échec de la réécriture car la ré-agrégation de la fonction
COUNTn'est pas prise en charge.
Si une fonction d'agrégation contient DISTINCT, la requête ne peut être réécrite que si la vue matérialisée et la requête d'origine possèdent la même clé d'agrégation. Dans le cas contraire, la réécriture est impossible.
-
Créez une vue matérialisée.
CREATE MATERIALIZED VIEW mv AS SELECT a, b, sum(DISTINCT c) AS sum, count(DISTINCT d) AS cnt FROM src GROUP BY a, b; -
Le tableau suivant illustre la réécriture des requêtes basée sur la vue matérialisée.
Requête d'origine
Requête réécrite
SELECT a, count(DISTINCT d) FROM src GROUP BY a, b;SELECT a, cnt FROM mv;SELECT a, count(c) FROM src GROUP BY a, b;Échec de la réécriture car la ré-agrégation de la fonction
COUNTn'est pas prise en charge.SELECT a, count(DISTINCT c) FROM src GROUP BY a;Échec de la réécriture car la colonne
anécessite une autre agrégation.
Exemple 3 : Réécriture avec une clause JOIN
Réécriture des entrées JOIN
-
Créez des vues matérialisées.
CREATE MATERIALIZED VIEW mv1 AS SELECT a, b FROM j1 WHERE b > 10; CREATE MATERIALIZED VIEW mv2 AS SELECT a, b FROM j2 WHERE b > 10; -
Le tableau suivant illustre la réécriture des requêtes basée sur les vues matérialisées.
Requête d'origine
Requête réécrite
SELECT j1.a,j1.b,j2.a FROM (SELECT a,b FROM j1 WHERE b > 10) j1 JOIN j2 ON j1.a=j2.a;SELECT mv1.a, mv1.b, j2.a FROM mv1 JOIN j2 ON mv1.a=j2.a;SELECT j1.a,j1.b,j2.a FROM (SELECT a,b FROM j1 WHERE b > 10) j1 JOIN (SELECT a,b FROM j2 WHERE b > 10) j2 ON j1.a=j2.a;SELECT mv1.a,mv1.b,mv2.a FROM mv1 JOIN mv2 ON mv1.a=mv2.a;
JOIN avec conditions de filtrage
-
Créez des vues matérialisées.
--Create a non-partitioned materialized view. CREATE MATERIALIZED VIEW mv1 AS SELECT j1.a, j1.b FROM j1 JOIN j2 ON j1.a=j2.a; CREATE MATERIALIZED VIEW mv2 AS SELECT j1.a, j1.b FROM j1 JOIN j2 ON j1.a=j2.a WHERE j1.a > 10; --Create a partitioned materialized view. CREATE MATERIALIZED VIEW mv LIFECYCLE 7 PARTITIONED BY (ds) AS SELECT t1.id, t1.ds AS ds FROM t1 JOIN t2 ON t1.id = t2.id; -
Le tableau suivant illustre la réécriture des requêtes basée sur les vues matérialisées.
Requête d'origine
Requête réécrite
SELECT j1.a,j1.b FROM j1 JOIN j2 ON j1.a=j2.a WHERE j1.a=4;SELECT a, b FROM mv1 WHERE a=4;SELECT j1.a,j1.b FROM j1 JOIN j2 ON j1.a=j2.a WHERE j1.a > 20;SELECT a,b FROM mv2 WHERE a>20;SELECT j1.a,j1.b FROM j1 JOIN j2 ON j1.a=j2.a WHERE j1.a > 5;(SELECT j1.a,j1.b FROM j1 JOIN j2 ON j1.a=j2.a WHERE j1.a > 5 AND j1.a <= 10) UNION SELECT * FROM mv2;SELECT key FROM t1 JOIN t2 ON t1.id= t2.id WHERE t1.ds='20210306';SELECT key FROM mv WHERE ds='20210306';SELECT key FROM t1 JOIN t2 ON t1.id= t2.id WHERE t1.ds>='20210306';SELECT key FROM mv WHERE ds>='20210306';SELECT j1.a,j1.b FROM j1 JOIN j2 ON j1.a=j2.a WHERE j2.a=4;Échec de la réécriture car la vue matérialisée ne contient pas la colonne
j2.a.
Extension d'un JOIN
-
Créez une vue matérialisée.
CREATE MATERIALIZED VIEW mv AS SELECT j1.a, j1.b FROM j1 JOIN j2 ON j1.a=j2.a; -
Le tableau suivant illustre la réécriture des requêtes basée sur la vue matérialisée.
Requête d'origine
Requête réécrite
SELECT j1.a, j1.b FROM j1 JOIN j2 JOIN j3 ON j1.a=j2.a AND j1.a=j3.a;SELECT mv.a, mv.b FROM mv JOIN j3 ON mv.a=j3.a;SELECT j1.a, j1.b FROM j1 JOIN j2 JOIN j3 ON j1.a=j2.a AND j2.a=j3.a;SELECT mv.a,mv.b FROM mv JOIN j3 ON mv.a=j3.a;
Ces trois scénarios de réécriture JOIN peuvent être combinés.
L'objectif de la réécriture de requête avec vue matérialisée étant d'accélérer les requêtes, MaxCompute privilégie les règles de réécriture offrant les meilleures performances. Une règle n'est pas appliquée si elle introduit des opérations qui entraîneraient une faible accélération.
Exemple 4 : Réécriture avec une clause LEFT JOIN
-
Créez une vue matérialisée.
CREATE MATERIALIZED VIEW mv LIFECYCLE 7( user_id, job, total_amount ) AS SELECT t1.user_id, t1.job, sum(t2.order_amount) AS total_amount FROM user_info AS t1 LEFT JOIN sale_order AS t2 ON t1.user_id=t2.user_id GROUP BY t1.user_id; -
Le tableau suivant illustre la réécriture d'une requête basée sur la vue matérialisée.
Requête d'origine
Requête réécrite
SELECT t1.user_id, sum(t2.order_amount) AS total_amount FROM user_info AS t1 LEFT JOIN sale_order AS t2 ON t1.user_id=t2.user_id GROUP BY t1.user_id;SELECT user_id, total_amount FROM mv;
Exemple 5 : Réécriture avec une clause UNION ALL
-
Créez une vue matérialisée.
CREATE MATERIALIZED VIEW mv LIFECYCLE 7( user_id, tran_amount, tran_date ) AS SELECT user_id, tran_amount, tran_date FROM alipay_tran UNION ALL SELECT user_id, tran_amount, tran_date FROM unionpay_tran; -
Le tableau suivant illustre la réécriture d'une requête basée sur la vue matérialisée.
Requête d'origine
Requête réécrite
SELECT user_id, tran_amount FROM alipay_tran UNION ALL SELECT user_id, tran_amount FROM unionpay_tran;SELECT user_id, tran_amount FROM mv;
Exemple 6 : Cas d'utilisation
-
Scénario
Prenons l'exemple d'une table de visites de pages nommée
visit_recordsqui enregistre l'ID de la page, l'ID de l'utilisateur et l'heure de visite pour chaque consultation. Une tâche d'analyse fréquente consiste à compter le nombre de visites pour différentes pages.Dans cette situation, créez une vue matérialisée sur
visit_recordsqui regroupe les données par ID de page et compte les visites pour chaque page. Exécutez ensuite des requêtes ultérieures sur cette vue matérialisée.La structure de
visit_recordsest la suivante :+------------------------------------------------------------------------------------+ | Field | Type | Label | Comment | +------------------------------------------------------------------------------------+ | page_id | string | | | | user_id | string | | | | visit_time | string | | | +------------------------------------------------------------------------------------+ -
Créez une vue matérialisée.
-- Create a materialized view for the visit_records table that groups by page ID and counts the visits for each page. CREATE MATERIALIZED VIEW count_mv AS SELECT page_id, count(*) FROM visit_records GROUP BY page_id; -
Exécutez la requête suivante :
SET odps.sql.materialized.view.enable.auto.rewriting=true; SELECT page_id, count(*) FROM visit_records GROUP BY page_id;Lors de l'exécution de cette instruction de requête, MaxCompute fait correspondre automatiquement la vue matérialisée
count_mvet lit les données pré-agrégées depuiscount_mv. -
Pour vérifier que la requête a été réécrite à l'aide de la vue matérialisée, exécutez la commande
EXPLAINsuivante :EXPLAIN SELECT page_id, count(*) FROM visit_records GROUP BY page_id;Le résultat suivant est renvoyé :
job0 is root job In Job job0: root Tasks: M1 In Task M1: Data source: doc_test_dev.count_mv TS: doc_test_dev.count_mv FS: output: Screen schema: page_id (string) _c1 (bigint) OKLa source de données
Data sourcedans le résultat renvoyé indique que la table lue par la requête est la vuecount_mvdu projetdoc_test_dev. Cela confirme que la vue matérialisée est efficace et que la réécriture de la requête a réussi.
Documents connexes
Pour plus d'informations sur les opérations relatives aux vues matérialisées, consultez Opérations sur les vues matérialisées.
Pour plus d'informations sur la fonctionnalité de mise à jour planifiée des vues matérialisées, consultez Mises à jour planifiées des vues matérialisées.