DataWorks は、MaxCompute V2.0 SQL エンジンを使用したスクリプト開発をサポートする MaxCompute Script ノードを提供します。このトピックでは、MaxCompute Script ノードの使用方法について説明します。
背景情報
MaxCompute SQL エンジンはスクリプトモードをサポートしており、複数の SQL 文を単一のスクリプトにまとめてコンパイルおよび実行できます。このモードは、ネストされたサブクエリや複数ステップの操作を含む複雑なクエリに最適です。スクリプト全体を一度に送信すると、統一された実行計画が生成されます。その後、ジョブはキューに入れられ、一度だけ実行されるため、リソース使用量がより効率的になります。詳細については、「スクリプトモードでの SQL」をご参照ください。
利用シーン
スクリプトモードは、書き換えが必要な多層のネストされたサブクエリや、複数の文に分割する必要がある複雑なスクリプトに適しています。
たとえば、スクリプトモードでは、変数に定数値を割り当てることができます。その後、SELECT * FROM variable 文をスカラーに変換し、他の列との計算で使用できます。定数値は、単一行テーブルに格納することもできます。次のコードは一例です。変換構文の詳細については、「サブクエリ (SUBQUERY)」をご参照ください。
@a := SELECT 10; -- 定数 10 を @a に割り当てます。SELECT col1 FROM t1 を実行して、単一行テーブル t1 から値を割り当てることもできます。
@b := SELECT key,VALUE+(SELECT * FROM @a) FROM t2 WHERE key >10000; -- テーブル t2 の value 列の値と @a の値を使用して計算を実行します。
SELECT * FROM @b;複数のデータソースからのデータが、たとえば一方が 01:00、もう一方が 07:00 のように、大きく異なる時間に利用可能になる場合、テーブル変数を使用して文を大規模な SQL スクリプトに結合することは適していません。
前提条件
MaxCompute コンピューティングリソースがDataWorks ワークスペースにアタッチされていること。
必要なテーブルが MaxCompute で作成され、サンプルデータがテーブルに追加されていること。詳細については、「テーブル作成文とサンプルテストデータ」をご参照ください。
構文
完全な MaxCompute スクリプトは、SET 文 > DDL 文 > DML 文 という構造に従います。各セクションには 0 個以上の文を含めることができますが、文の種類を混在させることはできません。アットマーク (@) で始まる文は変数を示します。構文は次のとおりです。
-- SET 文
SET odps.sql.type.system.odps2=true;
[SET odps.stage.reducer.num=***;]
[...]
-- DDL 文
CREATE TABLE table1 xxx;
[CREATE TABLE table2 xxx;]
[...]
-- DML 文
@var1 := SELECT [ALL | DISTINCT] select_expr, select_expr, ...
FROM table3
[WHERE where_condition];
@var2 := SELECT [ALL | DISTINCT] select_expr, select_expr, ...
FROM table4
[WHERE where_condition];
@var3 := SELECT [ALL | DISTINCT] var1.select_expr, var2.select_expr, ...
FROM @var1 JOIN @var2 ON ...;
INSERT OVERWRITE|INTO TABLE [PARTITION (partcol1=val1, partcol2=val2 ...)]
SELECT [ALL | DISTINCT] select_expr, select_expr, ...
FROM @var3;
[@var4 := SELECT [ALL | DISTINCT] var1.select_expr, var.select_expr, ... FROM @var1
UNION ALL | UNION
SELECT [ALL | DISTINCT] var1.select_expr, var.select_expr, ... FROM @var2;
CREATE [EXTERNAL] TABLE [IF NOT EXISTS] table_name
AS
SELECT [ALL | DISTINCT] select_expr, select_expr, ...
FROM var4;]制限事項
MaxCompute Script ノードには、次の制限事項が適用されます。
スクリプトモードは、SET 文、DML 文、および一部の DDL 文をサポートします。
DESCやSHOWのように画面に結果を表示する DDL 文はサポートされていません。スクリプトには、スタンドアロンの
SELECT文など、画面に結果を表示する文を 1 つしか含めることができません。複数含めるとエラーが発生します。スクリプト内で結果を表示するSELECT文を実行しないでください。スクリプトには、最大 1 つの
CREATE TABLE AS文を含めることができます。この文は、スクリプトの最後の文である必要があります。INSERT文と CREATE TABLE 文は別々に記述する必要があります。スクリプトモードでは、いずれかの文が失敗すると、スクリプト全体が失敗します。
スクリプトモードでは、すべての入力データが準備できた後にのみ、データを処理するためのジョブが生成されます。
スクリプトモードでは、同じスクリプト内でテーブルにデータを書き込んだ後、同じテーブルからデータを読み取るとエラーが発生します。
不正な例:
INSERT OVERWRITE TABLE src2 SELECT * FROM src WHERE key > 0; @a := SELECT * FROM src2; SELECT * FROM @a;正しい例:
このエラーを回避するには、文を次のように変更します。
@a := SELECT * FROM src WHERE key > 0; INSERT OVERWRITE TABLE src2 SELECT * FROM @a; SELECT * FROM @a;
MaxCompute Script ノードの作成
ノードの作成方法の詳細については、「MaxCompute Script ノードの作成」をご参照ください。
MaxCompute Script ノードの開発
MaxCompute Script ノードのエディターページで、必要に応じて以下のサンプルスクリプトコードを使用して開発できます。
基本的なスクリプト開発
MaxCompute スクリプトモードでは、SQL のコンパイルプロセスは簡単です。次の例は、MaxCompute Script ノードの使用方法を示しています。
CREATE TABLE IF NOT EXISTS dest(key string , VALUE bigint) ;
CREATE TABLE IF NOT EXISTS dest2(key string,VALUE bigint ) ;
@a := SELECT * FROM src WHERE VALUE >0;
@b := SELECT * FROM src2 WHERE key IS NOT NULL;
@c := SELECT * FROM src3 WHERE VALUE IS NOT NULL;
@d := SELECT a.key,b.value FROM @a LEFT OUTER JOIN @b ON a.key=b.key AND b.value>0;
@e := SELECT a.key,c.value FROM @a INNER JOIN @c ON a.key=c.key;
@f := SELECT * FROM @d UNION SELECT * FROM @e UNION SELECT * FROM @a;
INSERT OVERWRITE TABLE dest SELECT * FROM @f;
@g := SELECT e.key,c.value FROM @e JOIN @c ON e.key=c.key;
INSERT OVERWRITE TABLE dest2 SELECT * FROM @g;高度なスクリプト開発
MaxCompute スクリプトモードは IF 文をサポートします。IF 文を使用すると、プログラムは条件に基づいて実行ロジックを自動的に選択できます。MaxCompute の IF 構文は、条件に基づいて BOOLEAN 式と BOOLEAN スカラーサブクエリの 2 種類に分かれています。
IF 条件は BOOLEAN 式です。
このタイプの
IF ELSE文は、コンパイル段階でどのブランチを実行するかを決定します。次のコードは一例です。-- データ処理 SET odps.sql.allow.fullscan=true; SET odps.optimizer.cbo.rule.filter.black=LM; @date := '${var}'; @row TABLE(key int,VALUE bigint); -- 変数 row を宣言します。変数の型は Table で、スキーマは string です。 IF ( cast(@date AS bigint) % 2 == 0 ) BEGIN @row := SELECT key,VALUE FROM src1; END ELSE BEGIN @row := SELECT key,VALUE FROM src2; END INSERT OVERWRITE TABLE dest1 PARTITION(p='${var}') SELECT key,VALUE FROM @row;説明コード内で var という名前の変数が定義されています。スケジューリングパラメーター設定で var 変数に値を割り当てる必要があります。
IF 条件は BOOLEAN スカラーサブクエリです
このタイプの
IF ELSE文は、コンパイル段階でどのブランチを実行するかを決定できません。決定は実行時に行われます。そのため、複数のジョブを送信する必要があります。次のコードは一例です。@i bigint; @t TABLE(id bigint, VALUE bigint); IF ((SELECT count(*) FROM src WHERE a = '5') > 1) BEGIN @i := 1; @t := SELECT @i, @i*2; END ELSE BEGIN @i := 2; @t := SELECT @i, @i*2; END SELECT id, VALUE FROM @t;埋め込みユーザー定義関数 (UDF) の開発
また、MaxCompute スクリプトモードを使用して、Java または Python コードを SQL スクリプトに埋め込むことで、埋め込みユーザー定義関数 (UDF) を開発することもできます。詳細については、「埋め込み UDF」をご参照ください。
MaxCompute Script ノードのテスト
ノードのエディターページで、右側の Run Configuration セクションのパラメーターを構成します。
パラメーター
説明
コンピューティングリソース
アタッチ済みの MaxCompute コンピューティングリソースを選択します。
コンピューティングクォータ
作成したコンピューティングクォータ (Quota) を選択します。クォータは、ジョブに CPU やメモリなどのコンピューティングリソースを提供します。
利用可能なコンピューティングクォータがない場合は、ドロップダウンリストの [コンピューティングクォータの作成] をクリックして、MaxCompute コンソールでクォータを作成および構成します。
リソースグループ
コンピューティングリソースとの接続性テストに合格したスケジューリングリソースグループを選択します。詳細については、「ネットワーク接続ソリューション」をご参照ください。
ツールバーのパラメーターダイアログボックスで、作成した MaxCompute データソースを選択し、[実行] をクリックして MaxCompute Script タスクを実行します。
次のステップ
ノードのスケジューリング構成:プロジェクトフォルダ内のノードをスケジュールに従って実行する必要がある場合は、[スケジューリング] を設定し、ノードの右側にある [スケジューリングポリシー] セクションでスケジューリングプロパティを構成します。
ノードのデプロイメント:タスクを本番環境で実行する必要がある場合は、
アイコンをクリックしてデプロイメントプロセスを開始します。このプロセスにより、タスクが本番環境に公開されます。プロジェクトフォルダ内のノードは、本番環境に公開された後にのみスケジュールに従って実行されます。
テーブル作成文とサンプルテストデータ
例:
-- テーブルを作成します。
CREATE TABLE IF NOT EXISTS src(key string ,VALUE BIGINT);
INSERT INTO src VALUES ('1',11) ;
INSERT INTO src VALUES ('1',11) ;
CREATE TABLE IF NOT EXISTS src2(key string ,VALUE BIGINT);
INSERT INTO src2 VALUES ('1',22);
INSERT INTO src2 VALUES ('2',22);
CREATE TABLE IF NOT EXISTS src3(key string ,VALUE BIGINT);
INSERT INTO src3 VALUES ('1',33);
INSERT INTO src3 VALUES ('3',33);