読者です 読者をやめる 読者になる 読者になる

Oracle DB: Oracle Exadataの性能を引き出すバッチ処理設計

Oracle DB

本記事は私の経験によるもので、バッチ処理(AP)の設計/製造者向けの視点で書いています。全ての内容が正しいとは限りません。

Oracle Exadataは非常に高速なデータベースマシンですが、何でもかんでも高速にはなりません。バッチ処理を設計/製造する前に、Oracleが公開する資料に目を通してください。

※両リンクともPDFファイルへのリンクです。

特に設計/開発の勘所の11ページ以降は絶対に頭に入れたほうがいいです。

一括処理の4つのTips
バッチ処理の劇的な高速化を目指すために押さえておきたいこと
Tips-1:ループ処理を単一のSQLで記述
Tips-2:PL/SQLで負荷をExadataにオフロード
Tips-3:INDEX RANGE SCANよりFULL SCAN、NESTED LOOP結合よりHASH結合
Tips-4:DMLエラーハンドリングの活用

資料と被る内容もありますが、注意することを書きます。

★データ参照(INSERT時のSELECT含む)

  • とにかくFULL SCANさせる
    • FULL SCANのほうがINDEX RANGE SCANよりも早い。
    • つまりINDEXは作らない。
  • とにかくHASH JOINさせる
    • 絶対にNESTED LOOPS JOINさせない。やったら死ぬ。
    • 昔、根拠も教えられずにパフォーマンスが向上するため NOT IN より NOT EXISTS を使えと教え込まれたが、Exadataは NOT IN をどんどん使う。
  • 大量データ/テーブルのテーブル結合はしない
    • 大きくなる場合はオンメモリで処理できるよう絞るか分割する。
    • データ量を抑えられるようテーブル設計、データ作成処理を設計する。
    • 共通部品としてVIEWは使わない。

★データ作成/更新

  • 基本はダイレクトパスインサートを使う
    • ダイレクトパスインサートは「INSERT /*APPEND*/ SELECT」。
    • テーブルにはNOLOGGINGを設定する。
    • データ削除はTRUNCATEを利用する。DELETEではHWMが上昇し続け、パフォーマンスが大きく劣化する。
  • バッチ(ジョブ)の設計はTRUNCATE→ダイレクトパスインサートのリレーを意識する
    • 追加も、全洗替えも、当月分のみ洗替えも、更新であっても。
    • 当月分のみ洗替は当月と過去分のテーブルを分け、データ作成時は当月分のみTRUNCATE→ダイレクトパスインサートで処理し、参照時にVIEWでUNIONする。
    • 更新は更新後のデータを別テーブル作り、最後に入れ直す。
  • どうしても更新したい場合はMERGEを使う
    • 大量データはUPDATEよりMERGEのほうがずっと早い。
  • INSERT/UPDATE/DELETEの禁止
    • INSERTは使う必要性がない。
    • UPDATE/DELETEはくっそ遅くなる。
  • カーソル禁止
    • Exadataで処理するデータ件数を考えれば絶対ダメ。
    • 条件分岐は条件ごとに処理を分割する。