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

MaxCompute:マテリアライズドビューのクエリ再書き込み

最終更新日:Jan 01, 2026

MaxCompute は、フィルター条件や特定のオペレータータイプを含む元の SQL 文を、マテリアライズドビューを使用するように再書き込みできます。このトピックでは、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:集計関数を含むクエリ文の再書き込み

マテリアライズドビューの SQL 文とクエリ文の集約キーが同じ場合、すべての集計関数を再書き込みできます。集約キーが異なる場合、SUMMINMAX のみがサポートされます。

  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 種類の文は組み合わせることができます。クエリ文が再書き込み条件を満たしている場合、再書き込みが可能です。

クエリの再書き込みの目的は、クエリを高速化することです。MaxCompute は、最も効果的な再書き込みルールを優先します。再書き込みによって操作が追加され、パフォーマンスが向上しない場合、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;
  2. 次の表は、作成されたマテリアライズドビューに基づいて、元のクエリ文と再書き込みされたクエリ文を比較したものです。

    元のクエリ文

    再書き込みされたクエリ文

    SELECT t1.user_id, sum(t2.order_amout) 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, total_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 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 テーブルからデータを読み取ることを示しています。これは、マテリアライズドビューが有効であり、クエリの再書き込みが成功したことを示します。

関連トピック