2011-03-30 9 views
2

私たちはかなり広いテーブルBaseDataを持っています。そこには3300万行もあります。次に、すべての種類のパラメータを含むいくつかの他のテーブルに結合する更新クエリがあります。いくつかの関数が適用され、元のIdでグループが存在し、その結果がBaseDataテーブルにいくつかの列で書き戻されます。Oracle 10gエンタープライズでテーブル・ロックが更新文を高速化しますか?

このプロセスは非常に遅いので、私はそれをスピードアップする方法を検討しています。私はSQLServerで多くの経験を積んでいますので、このようなOracleの内部構造はすべてわかりません。

私が推測していることの1つは、更新中にOracleがすべての行のバージョンを作成し、任意の読者がその影響を受けていない行を読み取れることです。しかし、これはかなりのリソースを消費します。テーブルに書き込みロックを取るように更新する方法はありますか?そうすれば、すべての行のバージョンが作成されません。

大規模なアップデートのためのヒントはありますか?私たちはすでにそれをバッチに分割しました。各バッチはテーブルの別々のパーティションにあり、いくつかの更新は並行して実行されます。しかし、それでもずっと遅いです。

+1

Oracleは行のコピーを作成しておらず、読取り一貫性を確保するためにUNDOセグメントを使用しています。すぐに大量の更新を行う別のアプローチを提案します。 – tbone

+0

ステートメントの概要(またはステートメント自体)を投稿できますか? –

+0

こんにちは、すごく悲しいことです。 – gjvdkamp

答えて

3

簡単な答えは、Oracleでは、表に対して排他ロックを設定しても、他のセッションの読取りを妨げたり、データの読取り一貫性のあるビューを生成する必要がないということです。同様に、Oracleでは、セッションに「ダーティ・リード」を有効にするよう指示することもできません。

最初の質問は遅いです - それは機能に参加して適用するすべての作業ですか、それとも書き戻しですか? SELECT my_updated_resultset FROM BASEDATA JOIN...は更新ステートメントと比較してどのように機能しますか? BaseDataの読者と更新プロセスの間に競合があることを確認しましたか?また、それはビジネスにとって遅すぎるのですか、それともそうだと思うよりも遅いのですか?

また、パーティション交換を使用して更新を行うことも検討してください。ハイレベルの概念は、次のようになります。

  1. CREATE TABLE BASEDATA_XCHG as SELECT * FROM BASEDATA WHERE 1 = 0;
  2. INSERT /*+ append */ INTO BASEDATA_XCHG SELECT my_updated_resultset FROM BASEDATA PARTITION (ONLY_ONE_PARTITION) JOIN...
  3. BASEDATA_XCHGテーブルに必要なすべてのインデックスと制約を作成します。
  4. ALTER TABLE BASEDATA EXCHANGE PARTITION (ONLY_ONE_PARTITION) WITH BASEDATA_XCHG

あなたはBASEDATAテーブルのパーティション内のほとんどの行を更新している場合は、それらを更新していない - 新しいテーブルを作成し、それを交換します。 Tim Gormanには、この概念をより深くカバーする"Scaling to Infinity"という優れた論文があります。あなたはそれをチェックしたいかもしれません。アダムの答えに加えて

+0

こんにちは、thx。私たちはそれを見て、選択は更新よりずっと速いので、私がそこを見ていた理由です。また、スループットはバッチ内の行数に応じて指数関数的に増加するようです。我々は、より小さなバッチに作品を再配置しています。それはビジネスには遅すぎるので、実際にこれをスピードアップする必要があります。それ以外の場合は、これを破棄して、C++やcalcを使って行ってください。私はパーティションの交換を調べます。他のアイデアは、更新しないで、別のテーブルに挿入して元のものと結合することでした。 – gjvdkamp

3

実行ANは、あなたの更新ステートメントでEXPLAIN PLANをし、実行計画を確認してください。

ジョインとWHERE条件をサポートするインデックスを追加すると、クエリが高速化される可能性があります。

1

オラクルの使用は、私はこれらの大きなバッチプロセスにより使用されている「PROD」インスタンスをステージング領域上で実行されていないと仮定してい

(化SCNと共に、here続きを読む)読取り一貫性のためのセグメントを元に戻しますさまざまなプロセスの多く。大きなテーブルの25%以上(大まかな数字)を更新する場合は、更新を試みるよりもCTAS(選択テーブルを作成する)を行うほうが良いかもしれません。 CTASには、新しいテーブルの更新ロジックが含まれています。いったん終了したら、新しいテーブルにインデックス/許可/ etcを追加し、新しい名前をoldに変更します。また、CTASにパラレルヒントとノーログを追加して、潜在的に物事をスピードアップすることもできます。

+0

UNDOを生成するだけでなく、UNDOを生成するだけでなく、UNDOを生成するだけでなく、UNDOを生成するだけでなく、UNDOを生成すると同時に、UNDOを適用する必要があります。 –

+0

@Gary、Imは更新を避けて新しいテーブルを作成すると言っています – tbone

関連する問題