Oracle PL/SQLを使って大量データを処理する際、1行ずつループして処理を行うとパフォーマンスが低下します。
このようなケースで活躍するのが BULK COLLECT
と FORALL
です。
これらを活用することで、SQLとPL/SQL間のコンテキスト切り替えを最小限に抑え、大量データを効率的に処理できます。
BULK COLLECTとは?
BULK COLLECT
は、複数行のデータを一括でコレクション(配列型変数)に格納する仕組みです。
基本構文
使用例
1 2 3 4 5 6 7 8 9 10 11 |
DECLARE TYPE t_emp IS TABLE OF employees%ROWTYPE; l_emp t_emp; BEGIN SELECT * BULK COLLECT INTO l_emp FROM employees WHERE department_id = 10; DBMS_OUTPUT.PUT_LINE('取得件数: ' || l_emp.COUNT); END; |
✅ 通常のSELECT INTO
では1行しか取得できませんが、BULK COLLECT
を使うと複数行をまとめて変数に格納できます。
FORALLとは?
FORALL
は、コレクションに格納されたデータを使って一括処理(INSERT/UPDATE/DELETE)を行う構文です。
基本構文
使用例
BULK COLLECTとFORALLを組み合わせる
実務では、BULK COLLECT
で一括取得 → FORALL
で一括更新/削除といった流れがよく使われます。
処理フロー例
-
BULK COLLECT
で対象データを配列に取得 -
配列の内容を
FORALL
で一括更新 -
コミット
このように組み合わせることで、バッチ処理や大量データ更新におけるパフォーマンスを劇的に改善できます。
パフォーマンス比較
-
従来のループ処理
SQLとPL/SQL間で行き来が多くなり、数万件以上の処理では遅くなる -
BULK COLLECT + FORALL
コンテキストスイッチが最小化され、処理速度が数倍〜数十倍向上するケースもある
注意点
-
BULK COLLECT
で一度に大量データを取得するとメモリ不足の可能性あり
→LIMIT句
を組み合わせて分割取得が推奨 -
FORALL
はDML専用(SELECTでは使えない) -
例外処理は
SAVE EXCEPTIONS
を付けて制御することも可能
まとめ
-
BULK COLLECT
→ 複数行を一括取得 -
FORALL
→ 複数行を一括処理 -
大量データ処理では必須テクニック
-
メモリ管理や例外処理に注意しつつ使うと、バッチ処理の効率が大幅に改善
💡 実際のプロジェクトでは「数十万件以上のデータ更新」で特に効果が出やすいため、PL/SQLチューニングの定番として覚えておきましょう。