【小ネタ】Redshiftで大量データINSERT時にトランザクションログへの書き込みを回避する方法は?

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

こんにちは、DI部の川崎です。

Postgresqlでは、Ver. 9.1から「UNLOGGED TABLE」という機能が追加されています。

UNLOGGED TABLE

普通のテーブル、一時テーブル (TEMP TABLE) に加えて、UNLOGGED TABLE というテーブルタイプが追加されました。 UNLOGGED オプションを使うと、挿入 / 更新 / 削除の際にトランザクションログ (WAL) が書かれません。そのため、挿入や更新の多いテーブルを UNLOGGED にすることで、更新処理が大幅に高速化します。 一時テーブルとの違いは、他のセッションからも見えることと、サーバが正常終了する限りはデータが保持されることです。

Let's Postgres 「PostgreSQL 9.1 の新機能」より

http://lets.postgresql.jp/documents/technical/9.1/1#performance

既存のテーブルのレコードを加工して、別のテーブルに挿入する場合は、INSERT INTO ... SELECT構文を使うことが多いと思います。

insert into target_table (select * from source_table);

その場合、トランザクションログへの書き込み処理が発生してしまうと、パフォーマンスの低下を招きます。トランザクションログへの書き込みをスキップすることはできないでしょうか。

データベースのアーキテクチャによっては、同様のことをCREATE TABLE AS SELECT構文を使うことで、トランザクションログをスキップできる場合があると、とある方にアドバイスをもらいました。

Redshiftの場合はどうでしょうか? 早速試してみます。

demo01=# create table ctas_test1 (col1 int);
CREATE TABLE
demo01=# insert into ctas_test1 values (1);
INSERT 0 1
demo01=# begin; ← トランザクションを開始します
BEGIN
demo01=# create table ctas_test2 as select * from ctas_test1;
SELECT
demo01=# rollback; ← ロールバックします
ROLLBACK
demo01=# select * from ctas_test2;
ERROR:  relation "ctas_test2" does not exist

ロールバックできてしまいました。ということは、トランザクションログが有効である、トランザクションログはスキップされていない、ということになります。

RedshiftはPostgresqlのVer. 8台が基になっているそうです。従って、Ver. 9.1で追加された「UNLOGGED TABLE」の機能は備わっていない訳ですが、大量データを扱うことが多いDWHですので、ぜひトランザクションログへの書き込みを回避できる機能を、実装していただきたいと思います。

もし、別のやり方で回避する方法をご存知の方は、コメント欄からご一報いただけましたら嬉しいです。

  • Kamei Daisuke

    copy 文じゃダメでしょうか。