web-dev-qa-db-ja.com

OracleDELETEのパフォーマンスを向上させるための戦略

大きくなり始めているOracle11gのインストールがあります。このデータベースは、クラスター上で実行されている並列最適化システムのバックエンドです。プロセスへの入力は、最適化ステップからの出力とともにデータベースに含まれています。入力には、ロート構成データといくつかのバイナリファイル(11gのSecureFilesを使用)が含まれます。出力には、現在DBに保存されている1D、2D、3D、および4Dデータが含まれます。

DB構造:

/* Metadata tables */
Case(CaseId, DeleteFlag, ...) On Delete Cascade CaseId
OptimizationRun(OptId, CaseId, ...) On Delete Cascade OptId
OptimizationStep(StepId, OptId, ...) On Delete Cascade StepId

/* Data tables */
Files(FileId, CaseId, Blob) /* deletes are near instantateous here */

/* Data per run */
OnedDataX(OptId, ...)
TwoDDataY1(OptId, ...) /* packed representation of a 1D slice */

/* Data not only per run, but per step */
TwoDDataY2(StepId, ...)  /* packed representation of a 1D slice */
ThreeDDataZ(StepId, ...) /* packed representation of a 2D slice */
FourDDataZ(StepId, ...)  /* packed representation of a 3D slice */
/* ... About 10 or so of these tables exist */

刈り取りスクリプトが毎日登場し、DeleteFlag = 1のケースを探し、DELETE FROM Case WHERE DeleteFlag = 1を続行して、カスケードを続行できるようにします。

この戦略は読み取り/書き込みには最適ですが、データをパージしたいときに機能を上回っています。摩擦によってケースが削除されると、サイズにもよりますが20〜40分かかり、アーカイバのスペースが過負荷になることがよくあります。製品の次のメジャーバージョンは、問題を解決するために「ゼロから」アプローチを取ります。次のマイナーリリースは、データベースに保存されているデータの範囲内にとどまる必要があります。

したがって、マイナーリリースでは、削除のパフォーマンスを向上させることができ、せいぜいデータベースに中程度の変更を加える必要があるアプローチが必要です。

  1. REFパーティショニングですが、問題はどのようにですか? CaseでINTERVALを実行し、残りでREFを実行したいと思います ただし、サポートされていません 。トリガーを介してOptimizationRunCaseIdで手動で分割する方法はありますか?
  2. 削除のアーカイブ/やり直しログを無効にしますか?これに合うヒントが見つかりませんでした。それが実現可能かどうかさえわかりません。
  3. 切り捨てますか?これには、おそらく複雑なテーブル設定が必要になります。しかし、多分私は私のオプションのすべてを考慮していません。(回答ごとに、打たれた)

問題を説明するために、ケースごとの問題のデータは15MiBから1.5GiBの範囲で、20kから2M行の範囲です。

更新:DBの現在のサイズは約1.5TBです。

15
user7116

データベースにとって、データの削除は大変な仕事です。イメージの前に作成し、インデックスを更新し、REDOログを書き込み、データを削除する必要があります。これは遅いプロセスです。このタスクを実行するためのウィンドウを用意できる場合、最も簡単で最速の方法は、必要なデータを含む新しいテーブルを作成することです。古いテーブルを削除し、新しいテーブルの名前を変更します。これにはいくつかのセットアップ作業が必要です。これは明らかですが、作成することは非常に可能です。それほど劇的ではないステップは、削除が行われる前にインデックスを削除することです。私の投票はCTAS(Create Table As Select from)に行き、新しいテーブルを作成します。優れたパーティショニングスキーマは確かに役立ちます。おそらく次のリリースでは、Oracleはインターバルパーティショニングと参照パーティショニングを組み合わせることができます。持っていてとてもいいです。

ロギングの無効化....削除に対しては実行できませんが、CTASはnologgingを使用できます。準備ができたらバックアップを作成し、データファイルがある場合は必ずスタンバイデータベースに転送してください。

7
ik_zelf

いくつかの考え:

  1. すべての外部キーにインデックスがあると思います。 ON DELETE CASCADEは、Caseの削除が完了するまで行レベルのロックを保持し、インデックスがない場合はテーブルのロックを保持します。もちろん、非常に低速です。

  2. 延期された制約はありますか?これにより、Oracleがさまざまなテーブルの削除をカスケードする際の速度が低下する可能性があります。

  3. (削除カスケードに依存するのではなく)影響を受けるすべてのテーブルに対して個別に削除を実行しようとしましたか?それほど簡単ではありませんが、驚くかもしれません。

編集:

もう1つ考えました。ケーステーブルでソフト削除を行うことを検討できます。つまり、そのケースを検討する必要があるかどうかをアプリに通知するステータスフィールドがあります。このフラグにはさまざまな値がありますが、アクティブの場合は「A」、非アクティブの場合は「I」である可能性があります。他のテーブルへの結合で常にCaseを駆動/プライマリテーブルとして使用していると仮定すると、HARDによる削除をすべて一緒に回避できます(必要に応じて、スケジュールに関係なく時間のクリーンアップを行うこともあります)。もちろん、アプリはこのフラグを認識する必要があり、Caseテーブルに再び参加する必要があります。あなたの状況に合うかもしれないし、合わないかもしれません...

2
tbone

CASCADE DELETEは、内部的にslow-by-slow、er、row-by-rowで実行されます。

いくつかのオプション:

  1. パージジョブのスナップショットを作成して、CTASを使用してスクラッチテーブルにパージするすべてのケースを作成します。次に、パージジョブをそのテーブルでループさせ、各ケース(およびその子)を個別に削除します。これは、特に何百万もの子孫行に遭遇した場合、不快になる可能性があります。最近[businessredacted]でプロセスの1つを変更して、問題のある子カウントを持つ最終的な親を特定し、問題のある子テーブルに対する削除にrownumリミッターを使用する必要がありました( s)。高速ではありませんが、少なくとも、トランザクションの大きさに上限を設けることで、元に戻す/やり直しの管理の観点から安全です。

  2. 便宜上CASCADE DELETEを使用している場合、常にそうできるとは限りません。依存関係ツリーから「ボトムアップ」で削除する、より高度なパージルーチンを作成する必要があります。

  3. ソフト削除で元に戻す/やり直しを生成する余裕がある場合は、DeleteFlagで最終的な親を範囲パーティション化し、次にENABLE ROWMOVEMENTを使用してすべてのテーブルの子BY REFERENCEをパーティション分割できます。ソフト削除されたときに行を移動するための元に戻す/やり直しのコストが発生しますが、最終的にパージするときが来ると、DeleteFlag = 1のパーティションが切り捨てられます。

  4. ストレージの追加は比較的安価です。日付ベースの保持オプションがある場合はそれを使用し、ソフト削除オプションでアプリケーションのフロントエンドからデータを非表示にします。エレガントではありませんが、CASCADE DELETEもエレガントです。

1
Adam Musch

ライブデータベースにはお勧めしません。

  1. 削除が遅いテーブルを参照する外部キー制約を無効にしました。
  2. 削除を実行しました
  3. 外部キーを再度有効にしました。
0
keiki

Enterprise Managerを使用してAWRレポートを作成し、それを実行します statspackanalyzer これにより、システムのボトルネックに関する詳細な手順がわかります。 AWRレポートは、データベースが特定の時間に実行したことと、それにかかった時間に関するすべての種類のデータを含むテキストファイルです。そのstatspackアナライザーは、何をすべきかを指示する一種の自動DBAではありません。

Statspack Analyzerが有用である可能性があることを通知し、I/Oの分散に使用できるアイドルディスクがいくつかあるまで、パーティションを忘れます。

切り捨てについては考えないでください。コミットを強制します...

ところで、私はStatspack Analyzerとは提携していませんが、特にDBAがない場合は、Oracleにとって非常に実行可能な一般的なチューニングアプローチだと思います。

0
HAL 9000