MERGE コマンドを使用せずに列リストを指定してマージ操作を実行する
手順で説明しているマージオペレーションを実行するときは、すべてのステップを 1 つのトランザクションにまとめます。いずれかのステップが失敗した場合でも、トランザクションはロールバックされます。トランザクションを 1 つにすると、他にもコミットの回数が減るため、時間とリソースの節約になります。
列リストを指定してマージ操作を実行するには、以下の手順を実行します。
-
操作全体を 1 つのトランザクションブロックにまとめます。
BEGIN transaction; … END transaction;
-
次の疑似コードに示すように、ステージングテーブルを作成し、マージの対象となるデータを移します。
create temp table stage (like target); insert into stage select * from source where source.filter = 'filter_expression';
-
ステージングテーブルで内部結合を使用して、ターゲットテーブルを更新します。
-
UPDATE 句で、更新の対象となる列を明示的にリストします。
-
ステージングテーブルで内部結合を実行します。
-
分散キーがプライマリキーと異なり、分散キーが更新の対象でない場合は、冗長結合を分散キーに追加します。クエリでコロケーテッド結合を使用するかどうかを確認するには、EXPLAIN を使用してクエリを実行し、結合すべてに DS_DIST_NONE があるかどうかを確認します。詳細については、「クエリプランの評価」を参照してください。
-
ターゲットテーブルがタイムスタンプでソートされる場合、述語を追加し、ターゲットテーブルの範囲限定スキャンを活用します。詳細については、「Amazon Redshift クエリの設計のベストプラクティス」を参照してください。
-
マージですべての行を使用しない場合は、句を追加して、変更する行をフィルタリングします。例えば、1 つ以上の列に不等フィルタを追加して、変更されていない列を除外します。
-
問題が発生した場合に全体をロールバックできるよう、更新操作、削除操作、挿入操作を単一のトランザクションにまとめます。
次に例を示します。
begin transaction; update target set col1 = stage.col1, col2 = stage.col2, col3 = 'expression' from stage where target.primarykey = stage.primarykey and target.distkey = stage.distkey and target.col3 > 'last_update_time' and (target.col1 != stage.col1 or target.col2 != stage.col2 or target.col3 = 'filter_expression');
-
-
ターゲットテーブルで内部結合を使用して、ステージングテーブルから不要になった行を削除します。ターゲットテーブルの一部の行はすでにステージングテーブルの対応する行に一致し、その他は前のステップで更新されました。どちらの場合も、挿入のために必要ありません。
delete from stage using target where stage.primarykey = target.primarykey;
-
ステージングテーブルから残りの行を挿入します。ステップ 2 の UPDATE ステートメントで使用した列リストと同じものを VALUES 句内で使用します。
insert into target (select col1, col2, 'expression' from stage); end transaction;
-
ステージングテーブルを削除 (Drop) します。
drop table stage;