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

ORACLE
20160120-1

データ登録処理(INSERT)に時間に想定外の時間がかかることがあります。特に、インデックスが多くはられているテーブルに対して、大量のデータ登録を行うと時間がかかります。
本記事では、そのような状況下でのパフォーマンス解決策の一つ、ダイレクトパスインサートについて解説していきます。

ダイレクトパスインサートとは

ダイレクトパスインサートとは、バッファキャッシュを経由せずに、データファイルへ直接データ登録を反映する手法で、高速でデータ登録処理を行う事が出来ます。通常のデータ登録処理に比べて、処理時間が数分の1~10分の1程度に改善できます。
使い方は、対象のINSERT文にAPPENDヒントを付加するだけです。

INSERT /*+ APPEND */ INTO 表名 SELECT文;

以下具体的な使用例です。

-- 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)も不可な点です。

-- 以下、SELECT発行時にエラーになります
INSERT /*+ APPEND */ INTO test_table1
SELECT *
FROM   test_table2
;

SELECT *
FROM   test_table1
;

その他デメリット

参照整合性制約・トリガーが定義されている表には、ダイレクトパスインサートを使用できません。暗黙的に通常のインサート処理が行われます。

また、通常のデータ登録処理に比べて、一時表領域を多く消費します。

まとめ

データ登録処理(INSERT)でパフォーマンス不足が発生した時に、最小の修正で済むダイレクトパスインサート、魅力的です。
しかし、相応のデメリットもあります。
デメリットを考慮し、使用できる場面では修正策の一つとして検討してみて下さい。
例えば、新規テーブルの初期登録では、問題なく使用できるかと思います。

タイトルとURLをコピーしました