別表から大量データをINSERTする場合、APPENDヒントを利用することで、通常のINSERT処理ではなく、ダイレクトロードインサート処理を実行できます。このダイレクトロードインサート処理では、バッファ・キャッシュを経由せずにデータをINSERTすることができ、また最低限のREDO情報のみが生成されるため、通常のINSERT処理よりも大きくパフォーマンスを改善できる可能性があります。
それでは、実際に通常のINSERT処理とダイレクトロードインサート処理を実行し、実行統計、実行計画を比較してみましょう。今回は約90万件のデータをINSERTしています。
また、既存の表から新たに表を作成するときに利用するCREATE TABLE AS SELECT処理でも、最低限のREDO情報しか生成されません。図7は、同じ条件で新たに表を作成した場合の処理時間、REDO情報の生成量になります。
図5、図6、図7を比較すると、通常のINSERT処理よりもダイレクトロードインサート処理、CREATE TABLE AS SELECT処理の方が、処理時間、REDO情報の生成量ともに大幅に小さくなっていることが確認できます(ダイレクトロードインサート処理、CREATE TABLE AS SELECT処理で生成されたREDO情報は、データディクショナリに対する更新分のみとなります)。CREATE TABLE AS SELECT処理によるREDO情報の生成量は、AUTOTRACE機能にて実行統計の取得ができないため、図7のように調査する必要があります。また、データベースがアーカイブログモードに設定されている場合は、INSERT先の表の属性が「NOLOGGING」に設定されていないと、REDO情報が大量に生成されてしまうため注意が必要です。
これらの結果から、既存表にデータを追加する場合にはダイレクトロードインサート処理の利用を検討し、新規に表を作成する場合にはCREATE TABLE AS SELECT処理を利用するなど、処理に応じて使い分けを行うことが重要です。
なお、ダイレクトロードインサート処理では以下のような動作となるため、あらかじめ注意が必要です。
注意点 | 内容 |
---|---|
ハイ・ウォーター・マーク(以下、HWM)以降のブロックにINSERTされる | 通常のINSERT処理であれば、空きブロックにデータをINSERTすることが可能ですが、ダイレクトロードインサート処理ではHWM以降のブロックにデータがINSERTされます。そのため、通常のINSERT処理よりも領域の使用効率が低下してしまいます |
表単位のロックが獲得される | 通常のINSERT処理ではレコード単位でロックが獲得されますが、ダイレクトロードインサート処理では表単位でロックが獲得されます。そのため、ダイレクトロードインサート処理の実行中には、ほかのセッションによる同一表への更新処理は待たされることになります。パーティション表の1パーティションへのダイレクトロードインサート処理でも同様となるため、注意が必要です |
ダイレクトロードインサート処理後、トランザクションを完了する必要がある | ダイレクトロードインサート処理の実行直後は、必ずトランザクションを完了させる(COMMITもしくはROLLBACK)必要があります。もし、続けて同じ表にSELECTを実行すると、「ORA-12838:オブジェクトは、パラレルで変更された後は読込み/変更できません。」というエラーが発生してしまいます |
表1 ダイレクトロードインサート処理での注意点 |
Copyright © ITmedia, Inc. All Rights Reserved.