すべてのプロダクト
Search
ドキュメントセンター

MaxCompute:マテリアライズドビューのクエリリライト

最終更新日:Oct 17, 2026

MaxCompute は、クエリにフィルター条件や特定の演算子タイプが含まれている場合に、元の SQL クエリをマテリアライズドビューを使用するように書き換えることをサポートしています。

注意事項

  • マテリアライズドビューのクエリリライトの核となる原則は、マテリアライズドビューがクエリに必要なすべてのデータを含んでいる必要があるということです。これには、出力列、フィルター条件、集計関数、または JOIN 条件で使用されるすべての列が含まれます。マテリアライズドビューにない列をクエリが必要とする場合や、サポートされていない集計関数を使用する場合には、クエリを書き換えることはできません。

  • マテリアライズドビューのクエリリライトを有効にするには、クエリ文の前に次の構成を追加します。

    SET odps.sql.materialized.view.enable.auto.rewriting=true;

    マテリアライズドビューが無効な状態の場合、クエリリライトはサポートされません。この場合、クエリは高速化されずにソーステーブルに対して直接実行されます。

  • プロジェクト間の書き換え

    デフォルトでは、MaxCompute プロジェクトはクエリリライトに自身のマテリアライズドビューしか使用できません。他のプロジェクトのマテリアライズドビューを使用するには、クエリの前に次の構成を追加して、許可された MaxCompute プロジェクトのリストを指定する必要があります。

    SET odps.sql.materialized.view.source.project.white.list = <project_name1>,<project_name2>,<project_name3>;
  • LEFT/RIGHT JOIN または UNION ALL で定義されたマテリアライズドビューを使用した書き換えを有効にするには、クエリ文の前に次の構成を追加します。

    SET odps.sql.materialized.view.enable.substitute.rewriting=true;

サポートされている演算子タイプ

次の表は、MaxCompute がサポートするクエリリライトの演算子タイプと他のプロダクトのものを比較したものです。

演算子タイプ

分類

MaxCompute

BigQuery

Amazon Redshift

Hive

FILTER

完全な式の一致

サポート

サポート

サポート

サポート

部分的な式の一致

サポート

サポート

サポート

サポート

AGGREGATE

単一の AGGREGATE

サポート

サポート

サポート

サポート

複数の AGGREGATE

非サポート

非サポート

非サポート

非サポート

JOIN

JOIN タイプ

INNER JOIN

非サポート

INNER JOIN

INNER JOIN

単一の JOIN

サポート

非サポート

サポート

サポート

複数の JOIN

サポート

非サポート

サポート

サポート

AGGREGATE+JOIN

-

サポート

非サポート

サポート

サポート

例

例 1:フィルター条件による書き換え

  1. マテリアライズドビューを作成します。

    CREATE MATERIALIZED VIEW mv AS SELECT a,b,c FROM src WHERE a>5;
  2. 次の表に、このマテリアライズドビューの書き換え例を示します。

    元のクエリ

    書き換え後のクエリ

    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;

    マテリアライズドビューに列 d が含まれていないため、書き換えは失敗します。

    SELECT d, e FROM src WHERE a=10;

    マテリアライズドビューに列 d と e が含まれていないため、書き換えは失敗します。

    SELECT a, b FROM src WHERE a=1;

    マテリアライズドビューに a=1 のデータが含まれていないため、書き換えは失敗します。

例 2:集計関数による書き換え

マテリアライズドビューとクエリが同じ集計キーを共有している場合、すべての集計関数を書き換えることができます。集計キーが異なる場合、SUM、MIN、および MAX を使用した書き換えのみがサポートされます。

  1. マテリアライズドビューを作成します。

    CREATE MATERIALIZED VIEW mv AS 
    SELECT a, b, sum(c) AS sum, count(d) AS cnt FROM src GROUP BY a, b;
  2. 次の表に、このマテリアライズドビューに基づいてクエリがどのように書き換えられるかを示します。

    元のクエリ

    書き換え後のクエリ

    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;

    ビューは既に列 a と b を集計しているため、列 b を再度集計することはできず、書き換えは失敗します。

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

    COUNT 関数の再集計はサポートされていないため、書き換えは失敗します。

集計関数に DISTINCT が含まれている場合、マテリアライズドビューと元のクエリが同じ集計キーを持っている場合にのみクエリを書き換えることができます。そうでない場合、書き換えはできません。

  1. マテリアライズドビューを作成します。

    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. 次の表に、このマテリアライズドビューに基づいてクエリがどのように書き換えられるかを示します。

    元のクエリ

    書き換え後のクエリ

    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;

    COUNT 関数の再集計はサポートされていないため、書き換えは失敗します。

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

    列 a は別の集計を必要とするため、書き換えは失敗します。

例 3:JOIN 句による書き換え

JOIN 入力の書き換え

  1. マテリアライズドビューを作成します。

    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. 次の表に、このマテリアライズドビューに基づいてクエリがどのように書き換えられるかを示します。

    元のクエリ

    書き換え後のクエリ

    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

  1. マテリアライズドビューを作成します。

    --非パーティション化マテリアライズドビューを作成します。
    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 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. 次の表に、このマテリアライズドビューに基づいてクエリがどのように書き換えられるかを示します。

    元のクエリ

    書き換え後のクエリ

    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;

    マテリアライズドビューに列 j2.a が含まれていないため、書き換えは失敗します。

JOIN の拡張

  1. マテリアライズドビューを作成します。

    CREATE MATERIALIZED VIEW mv AS SELECT j1.a, j1.b FROM j1 JOIN j2 ON j1.a=j2.a;
  2. 次の表に、このマテリアライズドビューに基づいてクエリがどのように書き換えられるかを示します。

    元のクエリ

    書き換え後のクエリ

    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;

これら 3 つの JOIN 書き換えシナリオは組み合わせることができます。

マテリアライズドビューのクエリリライトの目的はクエリを高速化することであるため、MaxCompute は最高のパフォーマンスを提供する書き換えルールを優先します。高速化の効果が低い操作を導入するルールは適用されません。

例 4:LEFT JOIN 句による書き換え

  1. マテリアライズドビューを作成します。

    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, t1.job;
  2. 次の表に、このマテリアライズドビューに基づいてクエリがどのように書き換えられるかを示します。

    元のクエリ

    書き換え後のクエリ

    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;

例 5:UNION ALL 句による書き換え

  1. マテリアライズドビューを作成します。

    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. 次の表に、このマテリアライズドビューに基づいてクエリがどのように書き換えられるかを示します。

    元のクエリ

    書き換え後のクエリ

    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;

例 6:ユースケース

  1. シナリオ

    visit_records という名前のページ訪問テーブルがあり、各訪問のページ ID、ユーザー ID、訪問時間を記録しているとします。頻繁に行われる分析タスクは、異なるページの訪問数をカウントすることです。

    この状況では、visit_records 上にページ ID でグループ化し、各ページの訪問数をカウントするマテリアライズドビューを作成できます。その後、後続のクエリをこのマテリアライズドビューに対して実行できます。

    visit_records の構造は次のとおりです。

    +------------------------------------------------------------------------------------+
    | Field           | Type       | Label | Comment                                     |
    +------------------------------------------------------------------------------------+
    | page_id         | string     |       |                                             |
    | user_id         | string     |       |                                             |
    | visit_time      | string     |       |                                             |
    +------------------------------------------------------------------------------------+
  2. マテリアライズドビューを作成します。

    -- visit_records テーブルに対して、ページ ID でグループ化し、各ページの訪問数をカウントするマテリアライズドビューを作成します。
    
    CREATE MATERIALIZED VIEW count_mv AS SELECT page_id, count(*) FROM visit_records GROUP BY page_id;
  3. 次のクエリを実行します。

    SET odps.sql.materialized.view.enable.auto.rewriting=true; 
    SELECT page_id, count(*) FROM visit_records GROUP BY page_id;

    このクエリ文が実行されると、MaxCompute は自動的にマテリアライズドビュー count_mv を照合し、count_mv から事前集計されたデータを読み取ります。

  4. クエリがマテリアライズドビューを使用して書き換えられたことを確認するには、次の EXPLAIN コマンドを実行します。

    EXPLAIN SELECT page_id, count(*) FROM visit_records GROUP BY page_id;

    次の結果が返されます。

    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

    返された結果の Data source は、クエリが読み取ったテーブルが doc_test_dev プロジェクトの count_mv であることを示しています。これは、マテリアライズドビューが有効であり、クエリリライトが成功したことを示します。

関連ドキュメント