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:フィルター条件による書き換え
マテリアライズドビューを作成します。
CREATE MATERIALIZED VIEW mv AS SELECT a,b,c FROM src WHERE a>5;次の表に、このマテリアライズドビューの書き換え例を示します。
元のクエリ
書き換え後のクエリ
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 を使用した書き換えのみがサポートされます。
マテリアライズドビューを作成します。
CREATE MATERIALIZED VIEW mv AS SELECT a, b, sum(c) AS sum, count(d) AS cnt FROM src GROUP BY a, b;次の表に、このマテリアライズドビューに基づいてクエリがどのように書き換えられるかを示します。
元のクエリ
書き換え後のクエリ
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 が含まれている場合、マテリアライズドビューと元のクエリが同じ集計キーを持っている場合にのみクエリを書き換えることができます。そうでない場合、書き換えはできません。
マテリアライズドビューを作成します。
CREATE MATERIALIZED VIEW mv AS SELECT a, b, sum(DISTINCT c) AS sum, count(DISTINCT d) AS cnt FROM src GROUP BY a, b;次の表に、このマテリアライズドビューに基づいてクエリがどのように書き換えられるかを示します。
元のクエリ
書き換え後のクエリ
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 入力の書き換え
マテリアライズドビューを作成します。
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;次の表に、このマテリアライズドビューに基づいてクエリがどのように書き換えられるかを示します。
元のクエリ
書き換え後のクエリ
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
マテリアライズドビューを作成します。
--非パーティション化マテリアライズドビューを作成します。 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;次の表に、このマテリアライズドビューに基づいてクエリがどのように書き換えられるかを示します。
元のクエリ
書き換え後のクエリ
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 の拡張
マテリアライズドビューを作成します。
CREATE MATERIALIZED VIEW mv AS SELECT j1.a, j1.b FROM j1 JOIN j2 ON j1.a=j2.a;次の表に、このマテリアライズドビューに基づいてクエリがどのように書き換えられるかを示します。
元のクエリ
書き換え後のクエリ
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 句による書き換え
マテリアライズドビューを作成します。
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;次の表に、このマテリアライズドビューに基づいてクエリがどのように書き換えられるかを示します。
元のクエリ
書き換え後のクエリ
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 句による書き換え
マテリアライズドビューを作成します。
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;次の表に、このマテリアライズドビューに基づいてクエリがどのように書き換えられるかを示します。
元のクエリ
書き換え後のクエリ
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:ユースケース
シナリオ
visit_recordsという名前のページ訪問テーブルがあり、各訪問のページ ID、ユーザー ID、訪問時間を記録しているとします。頻繁に行われる分析タスクは、異なるページの訪問数をカウントすることです。この状況では、
visit_records上にページ ID でグループ化し、各ページの訪問数をカウントするマテリアライズドビューを作成できます。その後、後続のクエリをこのマテリアライズドビューに対して実行できます。visit_recordsの構造は次のとおりです。+------------------------------------------------------------------------------------+ | Field | Type | Label | Comment | +------------------------------------------------------------------------------------+ | page_id | string | | | | user_id | string | | | | visit_time | string | | | +------------------------------------------------------------------------------------+マテリアライズドビューを作成します。
-- visit_records テーブルに対して、ページ ID でグループ化し、各ページの訪問数をカウントするマテリアライズドビューを作成します。 CREATE MATERIALIZED VIEW count_mv AS SELECT page_id, count(*) FROM visit_records GROUP BY page_id;次のクエリを実行します。
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から事前集計されたデータを読み取ります。クエリがマテリアライズドビューを使用して書き換えられたことを確認するには、次の
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であることを示しています。これは、マテリアライズドビューが有効であり、クエリリライトが成功したことを示します。
関連ドキュメント
マテリアライズドビューの操作の詳細については、「マテリアライズドビューの操作」をご参照ください。
マテリアライズドビューの定期更新機能の詳細については、「マテリアライズドビューの定期更新」をご参照ください。