2017/12/07
データ登録処理(INSERT)に時間に想定外の時間がかかることがあります。特に、インデックスが多くはられているテーブルに対して、大量のデータ登録を行うと時間がかかります。
本記事では、そのような状況下でのパフォーマンス解決策の一つ、ダイレクトパスインサートについて解説していきます。
sponsored link
ダイレクトパスインサートとは
ダイレクトパスインサートとは、バッファキャッシュを経由せずに、データファイルへ直接データ登録を反映する手法で、高速でデータ登録処理を行う事が出来ます。通常のデータ登録処理に比べて、処理時間が数分の1~10分の1程度に改善できます。
使い方は、対象のINSERT文にAPPENDヒントを付加するだけです。
1 |
INSERT /*+ APPEND */ INTO 表名 SELECT文; |
以下具体的な使用例です。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
-- test_table2の項目aaaが'1'のデータを対象に、 -- 各項目(aaa・bbb・ccc)のデータを、test_table1に登録する INSERT /*+ APPEND */ INTO test_table1 (aaa ,bbb ,ccc ) SELECT aaa ,bbb ,ccc FROM test_table2 WHERE aaa = '1' ; |
パフォーマンス不足の解消に、便利そうなダイレクトパスインサートですが、相応のデメリットもあります。
デメリット
HWM以降のブロックにデータ登録される
通常のデータ登録処理では、データ削除処理(DELETE)で空いた領域があった場合、そこを優先的に格納先にします。
ダイレクトパスインサートでは、必ずハイウォーターマーク(HWM)以降のブロックにデータが格納されます。
日常的に使用する場合、セグメント領域が肥大化&断片化し検索効率の悪化します。
解消するためには、セグメント縮小(SHRINK等)が必要になります。
テーブルが表単位で排他ロックされる
ダイレクトパスインサートがコミット(もしくはロールバック)されるまでは、対象テーブルが表単位で排他ロックされます。つまり、他のトランザクションで同時に更新処理を行うことが出来ません。
日常的に使用する場合、並行する他の処理を考慮する必要があります。
トランザクション終了まで対象表にアクセス不可
ダイレクトパスインサートがコミット(もしくはロールバック)されるまでは、対象表にはトランザクション内ではアクセスが出来ません。注意する点は、更新系ではないデータ抽出(SELECT)も不可な点です。
1 2 3 4 5 6 7 8 9 |
-- 以下、SELECT発行時にエラーになります INSERT /*+ APPEND */ INTO test_table1 SELECT * FROM test_table2 ; SELECT * FROM test_table1 ; |
その他デメリット
参照整合性制約・トリガーが定義されている表には、ダイレクトパスインサートを使用できません。暗黙的に通常のインサート処理が行われます。
また、通常のデータ登録処理に比べて、一時表領域を多く消費します。
まとめ
データ登録処理(INSERT)でパフォーマンス不足が発生した時に、最小の修正で済むダイレクトパスインサート、魅力的です。
しかし、相応のデメリットもあります。
デメリットを考慮し、使用できる場面では修正策の一つとして検討してみて下さい。
例えば、新規テーブルの初期登録では、問題なく使用できるかと思います。