Oracleバッチ処理が一時表領域不足で異常終了したときのレアな原因と対処法

 過去に遭遇したトラブルについてメモしておきます。運用保守の担当をしていた頃です。深夜3時頃、携帯電話が鳴りました。夜間バッチ処理が異常終了したお知らせでした。タクシーでプロジェクトルームへ。

 どうやらパラレル実行したINSERT-SELECT文で一時表領域不足で異常終了していました。再実行してもダメ。結果その時はパラレル実行をやめると実行できました。

当時のSQL

 下のような感じでORが複数ありました。
【例】

insert into TABLE1
 select
  *
 from
 TABLE2
 where
  USER_ID = A0001
  OR USER_ID = B0001
  OR USER_ID = C0001
  OR USER_ID = D0001
  OR USER_ID = E0001


原因はOR拡張されたこと

 実行計画はOR拡張され、UNIONALLを使用して複数問合せに変換されていました。UNIONALLで複数問合せされることでメモリでは収まらなくなり、さらに一時表領域を使用。一時表領域が不足するほど肥大化していったのだと分かりました。

対策

 今回は一時表領域の拡張はせず、SQLの改修を行いました。改修といってもヒントを一行追加しただけです。NO_EXPANDというヒントで、OR拡張をしないようにオプティマイザに指示するものです。見事に解決しました。
 【修正例】

insert into TABLE1
 select /*+NO_EXPAND*/
  *
 from
  TABLE2
 where
  USER_ID = A0001
  OR USER_ID = B0001
  OR USER_ID = C0001
  OR USER_ID = D0001
  OR USER_ID = E0001



>>おすすめのORACLE参考書まとめ





【SQLでお困りの方にオススメ】
■SQLが遅くなる原因
・SQLが突然遅くなる原因と対応方法
・OracleSQLのレスポンスが遅い原因3つ
・JOINを使って表結合するとSQLが遅い!?
・SQLがパラレル実行されない原因

■SQLチューニングの基礎知識
・ORACLE SQLのヒントとは
・ORACLEのオプティマイザと実行計画について
・ORACLEのテーブルやインデックスの「統計情報」とは

■SQLチューニングの方法
・SLECT文が遅いときのインデックス作成によるチューニング方法
・Update文が遅いときのチューニング方法
・Delete文が遅いときのチューニング方法
・IN句をEXISTS句に置き換えするチューニング方法
・OR句の置き換えによるチューニング方法
・IN句の置き換えによるチューニング方法
・テーブルアクセスフルスキャンを無くしてチューニングする方法
・SQLでGROUP BYが遅いときのチューニング方法
・SQLのソート処理が遅い場合のチューニング方法

■表や索引の断片化対策
・プロが教えるORACLEの表や索引の断片化解消の見積り方法
・ORACLE表の断片化を解消する3つの方法

■SQLのチューニングの補足情報
・ORACLE SQLヒントの書き方
・SQLに複数のヒントの書き方
・OracleSQLに実装すべき3つのSQLヒント
・ORACLE表の統計情報取得日の確認方法
・「統計情報が古い」とはどういうことか
・ORACLE表の統計情報の取得方法

【自己学習したい方にオススメ】
・自宅で勉強用にORACLEデータベースを無償でダウンロードし構築する方法
・OracleMasterGold12cに一ヵ月で合格した勉強方法
・OracleMasterExpertパフォーマンス&チューニングに一ヵ月で合格した勉強方法
・手に職がない人はIT業界へ、オススメ資格と勉強方法
・OracleDBのチューニング勉強方法
・OraclePL/SQL勉強方法