サイトアイコン SE日記

【SQL】INSERT文のチューニング方法まとめ


本記事では、ORACLEデータベースで、SQLのINSERT文をチューニングする方法をまとめて紹介しています。

SQLの実行計画の見方や確認方法については↓で紹介していますので参考にしてください。
>>【ORACLE】SQLの実行計画の見方
>>【ORACLE】SQLの実行計画を取得する方法

INSERT文をチューニングする方法

INSERT文をチューニングする方法はある程度限られているかなと思います。
いくつか代表的なものを紹介します。

ダイレクト・パス・インサート

ダイレクト・パス・インサートとは、バッファキャッシュへの登録を省略し、DISK上のテーブルへ即時データを挿入するINSERTの方法です。

通常、ORACLEデータベースでINSERT文を実行すると、メモリ上のSGAという領域の中のバッファキャッシュというエリアに、書き込みが行われます。

一度、メモリ上のバッファキャッシュに書き込みを行った後、実際にデータが登録されているDISK上のテーブルに行が挿入されます。

ただし、ダイレクト・パス・インサートという、特殊なINSERTを行うことで、バッファキャッシュへのを登録を省略して、DISK上のテーブルへ直ちにデータを書き込むことが出来ます。

バッファキャッシュに登録する時間が短縮されことで、通常のINSERT文よりも格段に実効速度が速くなります。

ダイレクト・パス・インサートはAPPENDヒントを使うことで、実装することが出来ます。具体的には次のような形でヒントを追加します。

・ダイレクト・パス・インサートの実装方法

INSERT /*+ APPEND*/ INTO TABLE_A SELECT ~

※VALUESを使う場合は、INSERT /*+ APPEND_VALUES*/ INTO tab1 values ~という風にAPPEND_VALUESヒントを使うようです。

ちなみに、ダイレクト・パス・インサートには、いくつかの制約もあります。
最も重要な制約は、INSERTするテーブルをロックすることです。

他のSQLと同時に実行できなくなるので、事前に確認、注意が必要です。

nologgingを指定すること

INSERT文にnologgingを指定することで、当該INSERT文によるREDOログ(更新ログ)の書き出しを止めることが出来ます。

ダイレクト・パス・インサートと同様に実行速度は格段に速くなりますが、制約もあります。

REDOログ(更新ログ)を出力しないので、REDOログ(更新ログ)によるデータ復元などが出来なくなります。

・nologgingを指定する方法
 具体提起には、次のように、INTOの後ろにnologgingを指定します。

INSERT INTO nologging TABLE_A SELECT~

パラレル実行

INSERT文をパラレル実行することで、実行速度を速くする方法です。

これは1本のSQLを複数のORACLEプロセスによって分散して実行する方法です。

たまに、アプリケーションやプログラムを分割して”パラレル化する”という方がいますが、ここで紹介するのは、SQLを複数のプロセスで同時実行するという機能です。

例えば、データベースサーバのCPUが4つあり、夜間の時間帯の1つのバッチ処理のSQLに2CPU割り当てても問題ないといった場合に、2多重でパラレル実行を行います。

パラレル実行は、セッションでパラレル実行する方法とSQL単位にヒントでパラレル実行する方法の2種類があります。

・セッション単位
 ALTER SESSION文を使って、パラレル実行するように命令できます。パラレルの多重度は割り当てられるCPUの数を計算しつつ指定してください。

ALTER SESSION FORCE PARALLEL DML PARALLEL 4 ;

・ヒント
 SQL単位には、PARALLELヒントを使って多重度を指定します。さらにDML文で実行する際には、”ENABLE_PARALLEL_DML”というヒントを追記しておく必要があります。

INSERT /*+ PRALLEL(4) ENABLE_PARALLEL_DML*/ INTO TABLE_A SELECT ~

パラレル実行は、あくまでリソースに余裕があることを事前に確認した上で実行する必要があります。

リソースが枯渇すると、同じ時間帯に実行しているプログラムやバッチ処理が遅くなるなど、問題が発生する可能性があるので、十分に注意して実行してください。

INSERT先のテーブルのパーティション化

INSERTする先のテーブルをパーティション化する方法です。

パーティション化すると、データの格納領域を対象の範囲や値ごとに分割することが出来ます。

これによって、INSERT文の登録先が被りにくくなり、実行速度が速くなります。

特にパラレル実行したときに、実行速度が上がりやすくなります。

まとめ

INSERT文のチューニング方法は
 ・ダイレクトパスインサート
 ・nologging
 ・パラレル実行
 ・テーブルのパーティション化
などがあります。

なお、INSERT INTO SELECT ~のような場合、SELECTでデータを取得している時間がかかっている場合があり、SELECT文のチューニングが必要なケースもあります。

SELECT文のチューニングについては↓で紹介していますのでぜひ参考にしてください。
>>SELECT文のSQLチューニング方法まとめ

モバイルバージョンを終了