MaxCompute では、シンプルで使いやすい増分更新パイプラインを構築できるようにするため、Delta Live Materialized View (Delta Live MV) 機能を導入しました。本トピックでは、MaxCompute における Delta Live MV の操作について説明します。
概要
完全更新を使用するマテリアライズドビューと比較して、Delta Live Materialized View はデータの新鮮さと計算コストのバランスを取ります。既存の計算結果を最大限に活用し、インテリジェントな増分計算アルゴリズムを使用することで、計算コストを削減し、データの新鮮さを向上させます。
アーキテクチャ

主なメリット
MaxCompute の Delta Live MV 機能には、以下のメリットがあります。
宣言型 SQL、メンテナンス不要、自動化されたデータウェアハウスレイヤー。
簡素化されたデータウェアハウスアーキテクチャ。単一の計算ロジックおよびエンジンで、増分計算と完全計算の両方をサポートし、低遅延と高スループットを実現します。
コスト効率に優れています。データの新鮮さとコストのバランスを取り、統合された増分および完全 ETL 処理を効率的に処理します。
ユースケース
Delta Live MV 機能は、以下のシナリオに適しています。
オフラインワークロード向けニアリアルタイム処理
T+1 データウェアハウスを、分単位の遅延でニアリアルタイムデータウェアハウスへ進化させます。
増分処理と完全処理の統合
当日パーティションに対するニアリアルタイムの増分計算:データの新鮮さが高く、コスト効率の良い計算が求められるシナリオに最適です。
(オプション)過去のパーティションのバックフィル:大規模データ分析向けのデータのアーカイブまたは修正。
さまざまなタイプの SQL ロジックに対応した包括的な増分計算サポート。以下のような一般的な SQL オペレーターを含みます。
2 ストリーム INNER JOIN
2 ストリーム (LEFT/RIGHT) OUTER JOIN
GROUP BY 句のない集約関数を含む、ユーザー定義集約関数 (UDAF) を除くすべての集約関数 (AGGREGATE function)。
WINDOW
TableFunctionScan
UNION ALL
FILTER/Project
SUBQUERY
前提条件
ソーステーブルで Change Data Capture (CDC) が有効になっている必要があります。サポートされるソーステーブルのタイプは以下のとおりです。
Delta テーブルでCDC 機能が有効化されています。
別の Delta Live MV。Delta Live MV では、デフォルトで CDC が有効になります。
Delta Live MV では、RAND 関数やユーザー定義関数 (UDF) などの非決定的な計算を使用できません。
Delta Live MV の作成
構文
CREATE MATERIALIZED VIEW [IF NOT EXISTS][<project_name>.]<mv_name>
[LIFECYCLE <days>] -- ライフサイクルを指定します。
[BUILD DEFERRED] -- データを投入せずにテーブルスキーマのみを作成します。
[(<col_name> [COMMENT <col_comment>],...)] -- 列コメントを指定します。
[DISABLE REWRITE] -- クエリリライトでの使用可否を指定します。
[COMMENT <table comment>] -- テーブルコメントを指定します。
[PARTITIONED ON/BY (<col_name> [, <col_name>, ...]) -- パーティションテーブルとしてマテリアライズドビューを作成します。
[REFRESH EVERY <num> MINUTES/HOURS/DAYS] -- スケジュールされた更新間隔を設定します。
TBLPROPERTIES(
"refresh_mode"="incremental"
[,"enable_auto_refresh"="true"] -- 自動更新を有効にするかどうかを指定します。
[,"refresh_cron"="xx"] -- cron 式を使用して、間隔ベース、固定時刻、または混合の更新スケジュールを設定します。
[,"refresh_job_settings"="xx"]
)
AS <select_statement>;Delta Live MV の構文は、標準のマテリアライズドビューとほぼ互換性がありますが、以下の重要な違いがあります。
Delta Live MV をクラスター化テーブルとして作成することはできません。
Delta Live MV に対して
enable_auto_substituteパラメーターを true に設定することはできません。Delta Live MV は非同期マテリアライズドビューの一種であるため、ベーステーブルのデータが最新バージョンではない可能性があります。これは、enable_auto_substituteが true に設定されている場合に期待される動作と矛盾します。
パラメーター
パラメーター | 必須 | 説明 |
project_name | いいえ | プロジェクト名。 |
mv_name | はい | Delta Live MV の名前。 |
LIFECYCLE <days> | いいえ | データのライフサイクルを指定します。 |
BUILD DEFERRED | いいえ | 作成時にデータを投入せずに、テーブルスキーマのみを作成することを指定します。 |
col_name | いいえ | 列名。 |
col_comment | いいえ | 列コメント。 |
DISABLE REWRITE | いいえ | クエリリライトでの使用を防止します。 |
table comment | いいえ | テーブルコメント。 |
REFRESH EVERY <num> MINUTES/HOURS/DAYS | いいえ | スケジュールされた更新間隔を指定します。最小値は 1 分です。 |
enable_auto_refresh | いいえ | 自動更新を有効にするかどうかを指定します。
|
refresh_mode | いいえ | 更新モード。
|
refresh_cron | いいえ | 更新頻度を設定するための Cron 式を指定します。間隔ベース、固定時刻、または混合の更新スケジュールを設定できます。 値は QUARTZ Cron 形式の文字列です。詳細については、「Cron expression examples」をご参照ください。例: |
refresh_job_settings | いいえ |
|
select_statement | はい | SQL クエリ。 |
例
例 1:シンプルな Delta Live MV の作成
CDC が有効になっている Delta Table をソーステーブルとして使用し、5 分ごとに自動的に増分更新を行う mv1 という名前の Delta Live MV を定義します。
CREATE MATERIALIZED VIEW IF NOT EXISTS mv1
REFRESH EVERY 5 MINUTES
TBLPROPERTIES("enable_auto_refresh"="true", "refresh_mode"="incremental")
AS
SELECT name, COUNT(*) FROM source GROUP BY name;例 2:チューニングされた Delta Live MV の作成
SET odps.task.major.version=sql_flighting_dlmv;
CREATE MATERIALIZED VIEW IF NOT EXISTS part_dlmv_department
PRIMARY KEY(dept_id) -- プライマリキー `dept_id` は、ベーステーブルのプライマリキーに基づいて SQL ロジックから推論可能です。
-- 明示的な宣言は通常不要ですが、パーティション化された MV は現在 BUILD DEFERRED モードのみをサポートしており、
-- このモードでは自動キー推論がサポートされていないため、プライマリキーを明示的に宣言する必要があります。
LIFECYCLE 10
BUILD DEFERRED
PARTITIONED BY (pt)
TBLPROPERTIES('refresh_mode'='incremental',
'refresh_job_settings'='set odps.task.major.version=sql_flighting_dlmv;')
AS
SELECT *, get_setting('odps.custom.setting.department.pt') AS pt FROM t_department; MV 更新時のプライマリキー要件
現在、マテリアライズドビューの更新には、MV にプライマリキー (PK) が必要です。PK Delta Table とは異なり、MV は SQL ロジックから生成されます。MV 作成時にプライマリキーを明示的に宣言する必要があるかどうかは、以下の状況によります。
SQL ロジックからプライマリキーを推論できる場合
たとえば、SQL ステートメントに GROUP BY key が含まれている場合、MV のプライマリキーは自動的に key と推論され、明示的に宣言する必要はありません。
DESC EXTENDED mvName;コマンドを実行すると、推論されたプライマリキー列を確認できます。SQL ロジックからプライマリキーを推論できない場合
方法 1:自動推論を可能にするために、MV の SQL ロジックを変更して
GROUP BY句を追加します。方法 2:プライマリキーを明示的に宣言します。ただし、データが一意性制約を満たしている必要があります。システムは、各増分更新時にデータの一意性をベストエフォートでチェックします。初期ビルドフェーズ中のプライマリキーの一意性チェックのサポートは、今後のリリースで強化される予定です。
パーティション化された MV に関する特別な要件
パーティション化された MV は現在、
BUILD DEFERREDモードのみをサポートしています。このモードでは、自動プライマリキー推論がサポートされていません。そのため、プライマリキーを明示的に宣言する必要があります。
パーティション化された Delta Live MV
シナリオ 1:パーティション化された Delta Live MV を使用して、当日の増分データと過去の完全データを表現
SET odps.task.major.version=sql_flighting_dlmv;
CREATE MATERIALIZED VIEW IF NOT EXISTS part_dlmv_department
PRIMARY KEY(dept_id) -- プライマリキー `dept_id` は、ベーステーブルのプライマリキーに基づいて SQL ロジックから推論可能です。
-- 明示的な宣言は通常不要ですが、パーティション化された MV は現在 BUILD DEFERRED モードのみをサポートしており、
-- このモードでは自動キー推論がサポートされていないため、プライマリキーを明示的に宣言する必要があります。
LIFECYCLE 10
BUILD DEFERRED
PARTITIONED BY (pt)
TBLPROPERTIES('refresh_mode'='incremental',
'refresh_job_settings'='set odps.task.major.version=sql_flighting_dlmv;')
AS
-- t_department は、当日の増分データを記述するニアリアルタイム取り込みテーブルです。
SELECT *, get_setting('odps.custom.setting.department.pt') AS pt FROM t_department;
UNION ALL
-- history_t_department は、すべての過去データを含む履歴パーティションテーブルです。
SELECT * FROM history_t_department;シナリオ 2:group by key を使用して Delta Live MV のプライマリキーを推論
-- PK Delta Table
CREATE TABLE dlmv_base_table(
key STRING NOT NULL PRIMARY KEY,
value BIGINT,
value2 BIGINT
)
STORED AS ALIORC
TBLPROPERTIES (
'transactional' = 'true',
'cdc.insert.into.passthrough.enable' = 'true',
'acid.cdc.mode.enable' = 'true',
'acid.cdc.build.async' = 'false'
);
CREATE MATERIALIZED VIEW dlmv_pt
PRIMARY KEY(value) -- プライマリキー `value` は、SQL ロジック (GROUP BY value) から推論可能です。
-- 明示的な宣言は通常不要ですが、パーティション化された DLMV は現在 BUILD DEFERRED モードのみをサポートしており、
-- このモードでは自動キー推論がサポートされていないため、プライマリキーを明示的に宣言する必要があります。
BUILD DEFERRED
PARTITIONED BY (pt)
TBLPROPERTIES (
'refresh_mode' = 'incremental',
'enable_auto_refresh' = 'true'
)
AS SELECT *, get_setting('odps.custom.setting.dlmv_pt.pt') AS pt FROM (SELECT value, MAX(value2) FROM dlmv_base_table GROUP BY value) t;シナリオ 3:ベーステーブルのプライマリキーから Delta Live MV のプライマリキーを推論
-- PK Delta Table
CREATE TABLE dlmv_base_table(
key STRING NOT NULL PRIMARY KEY,
value BIGINT,
value2 BIGINT
)
STORED AS ALIORC
TBLPROPERTIES (
'transactional' = 'true',
'cdc.insert.into.passthrough.enable' = 'true',
'acid.cdc.mode.enable' = 'true',
'acid.cdc.build.async' = 'false'
);
CREATE MATERIALIZED VIEW dlmv_pt
PRIMARY KEY(key) -- プライマリキー `key` は、SQL ロジック (ベーステーブルの PK から派生) から推論可能です。
-- 明示的な宣言は通常不要ですが、パーティション化された DLMV は現在 BUILD DEFERRED モードのみをサポートしており、
-- このモードでは自動キー推論がサポートされていないため、プライマリキーを明示的に宣言する必要があります。
BUILD DEFERRED
PARTITIONED BY (pt)
TBLPROPERTIES (
'refresh_mode' = 'incremental',
'enable_auto_refresh' = 'true'
)
AS
SELECT key, value, value2, get_setting('odps.custom.setting.dlmv_pt.pt') as pt FROM dlmv_base_table;シナリオ 4:Delta Live MV のプライマリキーを推論できない
-- PK Delta Table
CREATE TABLE dlmv_base_table(
key STRING NOT NULL PRIMARY KEY,
value BIGINT,
value2 BIGINT
)
STORED AS ALIORC
TBLPROPERTIES (
'transactional' = 'true',
'cdc.insert.into.passthrough.enable' = 'true',
'acid.cdc.mode.enable' = 'true',
'acid.cdc.build.async' = 'false'
);
# 1. PK 列を明示的に宣言します。
CREATE MATERIALIZED VIEW dlmv_pt
PRIMARY KEY(value) -- SQL ロジックから PK を推論できませんが、データが PK の一意性を満たしていることが分かっているため、PK を明示的に宣言する必要があります。
BUILD DEFERRED
PARTITIONED BY (pt)
TBLPROPERTIES (
'refresh_mode' = 'incremental',
'enable_auto_refresh' = 'true'
)
AS
SELECT value, value2, get_setting('odps.custom.setting.dlmv_pt.pt') as pt FROM dlmv_base_table;
# 2. PK 推論を可能にするために SQL ロジックを変更します。
-- 'value' 列の一意性を保証できない場合は、以下のように GROUP BY 句を使用してロジックを変更してください。
CREATE MATERIALIZED VIEW dlmv_pt
PRIMARY KEY(value) -- PK `value` は、SQL ロジック (GROUP BY value) から推論可能になりました。
-- 明示的な宣言は通常不要ですが、パーティション化された DLMV は現在 BUILD DEFERRED モードのみをサポートしており、
-- このモードでは自動キー推論がサポートされていないため、プライマリキーを明示的に宣言する必要があります。
BUILD DEFERRED
PARTITIONED BY (pt)
TBLPROPERTIES (
'refresh_mode' = 'incremental',
'enable_auto_refresh' = 'true'
)
AS SELECT value, MAX(value2), get_setting('odps.custom.setting.dlmv_pt.pt') as pt FROM dlmv_base_table GROUP BY value;非パーティション化された Delta Live MV
シナリオ 1: group by key を使用して Delta Live MV のプライマリキーを推論する
-- PK Delta Table
CREATE TABLE dlmv_base_table(
key STRING NOT NULL PRIMARY KEY,
value BIGINT,
value2 BIGINT
)
STORED AS ALIORC
TBLPROPERTIES (
'transactional' = 'true',
'cdc.insert.into.passthrough.enable' = 'true',
'acid.cdc.mode.enable' = 'true',
'acid.cdc.build.async' = 'false'
);
CREATE MATERIALIZED VIEW dlmv
-- PRIMARY KEY(value) -- PK `value` は、SQL ロジック (GROUP BY value) から推論可能であるため、明示的な宣言は不要です。
TBLPROPERTIES (
'refresh_mode' = 'incremental',
'enable_auto_refresh' = 'true'
)
AS SELECT value, MAX(value2) FROM dlmv_base_table GROUP BY value;シナリオ 2:ベーステーブルのプライマリキーから Delta Live MV のプライマリキーを推論
-- PK Delta Table
CREATE TABLE dlmv_base_table(
key STRING NOT NULL PRIMARY KEY,
value BIGINT,
value2 BIGINT
)
STORED AS ALIORC
TBLPROPERTIES (
'transactional' = 'true',
'cdc.insert.into.passthrough.enable' = 'true',
'acid.cdc.mode.enable' = 'true',
'acid.cdc.build.async' = 'false'
);
CREATE MATERIALIZED VIEW dlmv
-- PRIMARY KEY(key) -- PK `key` は、SQL ロジック (ベーステーブルの PK から派生) から推論可能であるため、明示的な宣言は不要です。
TBLPROPERTIES (
'refresh_mode' = 'incremental',
'enable_auto_refresh' = 'true'
)
AS
SELECT key, value, value2 FROM dlmv_base_table;シナリオ 3:Delta Live MV のプライマリキーを推論できない
-- PK Delta Table
CREATE TABLE dlmv_base_table(
key STRING NOT NULL PRIMARY KEY,
value BIGINT,
value2 BIGINT
)
STORED AS ALIORC
TBLPROPERTIES (
'transactional' = 'true',
'cdc.insert.into.passthrough.enable' = 'true',
'acid.cdc.mode.enable' = 'true',
'acid.cdc.build.async' = 'false'
);
# 1. PK 列を明示的に宣言します。
CREATE MATERIALIZED VIEW dlmv
PRIMARY KEY(value) -- SQL ロジックから PK を推論できませんが、データが PK の一意性を満たしていることが分かっているため、PK を明示的に宣言する必要があります。
TBLPROPERTIES (
'refresh_mode' = 'incremental',
'enable_auto_refresh' = 'true'
)
AS
SELECT value, value2 FROM dlmv_base_table;
# 2. PK 推論を可能にするために SQL ロジックを変更します。
-- 'value' 列の一意性を保証できない場合は、以下のように GROUP BY 句を使用してロジックを変更してください。
CREATE MATERIALIZED VIEW dlmv
-- PRIMARY KEY(value) -- PK `value` は、SQL ロジック (GROUP BY value) から推論可能になったため、明示的な宣言は不要です。
TBLPROPERTIES (
'refresh_mode' = 'incremental',
'enable_auto_refresh' = 'true'
)
AS SELECT value, MAX(value2) FROM dlmv_base_table GROUP BY value;例 3:単一の MV パーティションの更新
パーティション化された Delta Live MV を作成する際は、DDL 操作のみを実行する BUILD DEFERRED キーワードを含める必要があります。
-- Delta Live MV を作成します。
CREATE MATERIALIZED VIEW dlmv_pt
PRIMARY KEY(value) BUILD DEFERRED PARTITIONED BY (ds) TBLPROPERTIES
('refresh_mode'='incremental', 'enable_auto_refresh'='true')
AS SELECT value, AVG(value2), ds FROM dlmv_pt_src GROUP BY value, ds;
-- 単一のパーティションを更新します。
ALTER MATERIALIZED VIEW dlmv_pt REBUILD PARTITION(ds='20250730');Delta Live MV の更新に関する詳細については、「手動更新」をご参照ください。
例 4:パラメーター化された Delta Live MV の作成
パラメーター化された定義を使用して、オフラインパーティションジョブを増分ジョブに移行できます。
get_setting関数は、セッションフラグで設定されたパラメーター値を取得します。パラメーター名には、odps.custom.settingというプレフィックスを付ける必要があります。従来のオフラインジョブでは、
${biz_date}のような変数を、get_setting(odps.custom.setting.xx)に置き換えて、定義をパラメーター化します。Delta Live MV の更新ステートメントの前に、セッションフラグ
set odps.custom.setting.xx=yyを追加します。ランタイム時に、MaxCompute オプティマイザーが Delta Live MV 内の
get_setting(odps.custom.setting.xx)を自動的にyyに置き換えます。
以下に例を示します。
-- Delta Live MV を作成します。
CREATE MATERIALIZED VIEW mv1
BUILD DEFERRED -- DDL 操作のみを実行し、データは投入しません。
PARTITIONED BY (ds)
REFRESH EVERY 5 minutes
TBLPROPERTIES("enable_auto_refresh"="true", "refresh_mode"="incremental")
AS
SELECT A.* FROM A JOIN B ON A.c1 = B.c1
AND A.ds=get_setting('odps.custom.setting.bizdate.a')
AND B.ds=get_setting('odps.custom.setting.bizdate.b');
-- 更新ロジック。DataWorks はスケジューリング中に ${biz_date} および ${yesterday} を自動的に置き換えます。
SET odps.custom.setting.bizdate.a=${biz_date};
SET odps.custom.setting.bizdate.b=${yesterday};
ALTER MATERIALIZED VIEW mv1 REBUILD PARTITION(ds=${biz_date});Delta Live MV の管理
Delta Live MV の削除
DROP MATERIALIZED VIEW [IF EXISTS] [<project_name>.]<mv_name>;手動更新
Delta Live MV を手動で更新できます。単一パーティションの更新のみがサポートされています。構文は、標準のマテリアライズドビューと同じです。
ALTER MATERIALIZED VIEW [<project_name>.]<mv_name>
REBUILD [PARTITION(<ds>=max_pt(<table_name>),<expression1>...)];この構文では、ds がパーティション列です。
自動更新の無効化
次のコマンドを実行して、マテリアライズドビューの TBLPROPERTIES を変更し、自動更新機能を無効にします。
ALTER MATERIALIZED VIEW <mv_name> SET TBLPROPERTIES("enable_auto_refresh"="false");自動更新の再開
次のコマンドを実行して、マテリアライズドビューの TBLPROPERTIES を変更し、自動更新を有効化または再開します。
ALTER MATERIALIZED VIEW <mv_name> SET TBLPROPERTIES("enable_auto_refresh"="true");更新頻度の変更
次のコマンドを実行して、Delta Live MV の更新頻度を変更します。
ALTER MATERIALIZED VIEW <mv_name>
SET TBLPROPERTIES("refresh_interval_minutes"="xx");refresh_interval_minutes パラメーターの最小値は 1 です。この値は、ベーステーブルの CDC ライフサイクルよりも短く設定することを推奨します。
Delta Live MV の表示
データ変更履歴の表示
次のコマンドを実行して、Delta Live MV のデータ変更履歴を表示します。
SHOW HISTORY FOR TABLE <mv_name>;サンプル結果:
ObjectType ObjectId ObjectName VERSION(LSN) Time Operation
TABLE d95ec7015e8b432e8e0092d01da962a9 incremental_mv 0000000000000001 2024-08-18 21:06:32 CREATE
TABLE d95ec7015e8b432e8e0092d01da962a9 incremental_mv 0000000000000002 2024-08-18 21:11:13 UPDATE更新履歴の表示
次のコマンドを実行して、Delta Live MV の更新履歴を表示します。
SELECT * FROM
Delta_Live_MV_Refresh_History(['<project_name>', '<schema_name>',]'<table_name>');パラメーター
パラメーター | 説明 |
project_name | プロジェクト名。 |
schema_name | スキーマ名。 |
table_name | テーブル名。 |
戻り値
パラメーター | 説明 |
project_name | Delta Live MV を含むプロジェクト。 |
schema_name | Delta Live MV を含むスキーマ。 |
name | Delta Live MV の名前。 |
refresh_start_time | 更新開始時刻。 |
refresh_end_time | 更新終了時刻。ジョブの状態が RUNNING の場合、このフィールドの値は NULL です。 |
instance_id | ジョブ ID。この ID を使用して Logview を取得できます。 |
duration_in_seconds | 更新の持続時間(秒)。 |
state | ジョブの状態。
|
refresh_trigger | 更新をトリガーした方法。
|
refresh_mode | 更新モード。
|
error_message | 更新が失敗した場合のエラーメッセージ。更新が成功した場合は、このフィールドは NULL です。 |
source_tables | Delta Live MV で使用されるベーステーブルの名前と、それらに対応するバージョン。 |
numInsertedRows | 挿入された行数。 |
numDeletedRows | 削除された行数。 |
課金
Delta Live MV には、計算料金とストレージ料金が発生します。課金方法は、標準的なマテリアライズドビュー操作と同じです。
計算料金
Delta Live MV の作成または更新時に計算ジョブが開始される場合があります。これらのジョブは計算リソースを消費し、計算料金が発生します。課金ルールは、標準的な SQL ジョブと同じです。
自動更新機能がデータの変更を検出しなかった場合、更新ジョブは開始されず、料金は発生しません。
Delta Live MV を専用のプロジェクトに配置すると、自動更新ジョブとそのリソース消費および料金を追跡しやすくなります。
ストレージ料金
Delta Live MV のストレージは、標準的なマテリアライズドビューまたは通常のテーブルと同様に課金されます。
特定のオペレーターでは、Delta Live MV が状態ベースの増分計算アルゴリズムを使用するため、追加のストレージスペースを消費する内部状態表が生成される場合があります。
Delta Live MV には、増分 CDC および Time Travel のためのストレージオーバーヘッドが必要です。このストレージオーバーヘッドは、標準的な Delta Table と同様です。