Tous les produits
Search
Centre de documentation

MaxCompute:Réécriture de requête avec vue matérialisée

Dernière mise à jour :Aug 21, 2026

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 JOIN ou UNION 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

  1. Créez une vue matérialisée.

    CREATE MATERIALIZED VIEW mv AS SELECT a,b,c FROM src WHERE a>5;
  2. 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 d et e.

    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.

  1. 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;
  2. 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 a et b, donc la colonne b ne 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 COUNT n'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.

  1. 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;
  2. 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 COUNT n'est pas prise en charge.

    SELECT a, count(DISTINCT c) FROM src GROUP BY a;

    Échec de la réécriture car la colonne a nécessite une autre agrégation.

Exemple 3 : Réécriture avec une clause JOIN

Réécriture des entrées JOIN

  1. 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;
  2. 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

  1. 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;
  2. 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

  1. 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;
  2. 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

  1. 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;
  2. 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

  1. 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;
  2. 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

  1. Scénario

    Prenons l'exemple d'une table de visites de pages nommée visit_records qui 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_records qui 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_records est la suivante :

    +------------------------------------------------------------------------------------+
    | Field           | Type       | Label | Comment                                     |
    +------------------------------------------------------------------------------------+
    | page_id         | string     |       |                                             |
    | user_id         | string     |       |                                             |
    | visit_time      | string     |       |                                             |
    +------------------------------------------------------------------------------------+
  2. 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;
  3. 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_mv et lit les données pré-agrégées depuis count_mv.

  4. Pour vérifier que la requête a été réécrite à l'aide de la vue matérialisée, exécutez la commande EXPLAIN suivante :

    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)
    
    OK

    La source de données Data source dans le résultat renvoyé indique que la table lue par la requête est la vue count_mv du projet doc_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