2011-10-13 8 views
2

我々のデータ処理アプリケーションのパフォーマンスのベンチマークを実行しているとき、我々はFOO_TABLE空で始まり、その後、別のスレッドでは、我々は同じレコードを選択しながら、のようなクエリを使用して処理することから一つのスレッドからレコードを挿入します。一緒にOracleはクエリプランをどのくらい頻繁に変更しますか?

select * from FOO_TABLE where ID > ? 

1つのチャンクで選択されたレコードの数を制限するために、Javaでの

stmt.setMaxRows(5000); 

をJavaで使用します。 (IDにギャップがあるため、ここではBETWEENは使用したくありません)。テストが停止されるまで、チャンクの処理を5000回続けます。

ここでは、アプリケーションのパフォーマンスが低下し、Oracle側で何が起きているかを確認したところ、「select * from FOO_TABLE where ID>」というクエリプランに気づいたことに驚きました。 IDにPKインデックスを使用する代わりにテーブルスキャンを行います。

アプリケーションを再起動した後(ただし、表を切り捨てずに)、Oracleはreasonに戻り、PK索引を使用しました。

私の説明は、空がほぼ空だったときにテーブルをスキャンすることをお勧めしますが、このクエリプランを改訂していないと考えました。これは私の質問に私をもたらします:どのくらいの頻度でOracleがクエリプランを改訂しますか?

私はアプリケーションを再起動したのでしょうか? 1時間後にプールされた接続をリサイクルするので、私はこれについていくつか疑問を抱いています(したがって、1時間以上接続できません)。

一定の時間が経過したのでしょうか?

テーブルがほとんど空であっても、Oracleがスキャンを実行しないようにする方法はありますか?

環境情報: - を11gの神託 - JDBCクライアント(Java 6の)

UPDATE 2011年10月25日:私は、Oracle 10gで回帰テストを行なったし、問題は同じであるので、それが発生していないですどちらも動的カーソルの共有によって固定されます。 Markが最初に述べたように、構造の変更やテーブル統計の再計算といった大きなイベントがない限り、計画は改訂されません。

最終的に私はPKによるアクセスを強制するためのヒントを追加しましたが、オプティマイザがこれを理解できるはずだったと思います。検索条件に一致するPKがある場合は、小さなテーブルでもパフォーマンスの差はあまり重要ではありません。

答えて

2

Oracleのバージョンは?文が共有プールにはすでにいなかった場合は一般的に、

select * from FOO_TABLE where ID > ? 

はハード解析さになるだろう

。これは、実行計画が生成される時間です。

その後、何かが無効化されない限り、実行計画は変更されません。 (テーブルへのインデックスの追加/削除、テーブルからのカラムの削除、テーブルの統計の再計算など)。

11gには適応カーソル共有があります(これが私がOracleのバージョンに尋ねた理由です)。多くの詳細を理解することなく、バインド変数の値を覗き込み、計画変更が必要かどうかを新しいバインド値。

+0

実際11gです。だから、あなたはある時点で計画を改訂することをオラクルが期待していますか?約1日と数千万件の記録が残っていたが、計画は変わっていなかった。事実、このテーブルスキャンのために、アプリケーションのスループットはほとんど0に落ちました。あなたが言及している適応カーソル共有には特別な設定が必要ですか? –

+0

すでに使用中のプランとは異なるプランを必要とするかもしれない別のバウンド値がない限り、プランは適応カーソル共有のもとで変更されません。多くのデータを表にロードする場合は、統計を再集計する方がよいでしょう。 –

1

Adaptive Cursor共有は、11.1から始まるオプティマイザの組み込み機能です。 Oracleのどのバージョンを実行していますか? (フルバージョンナンバー?)私は11gの11.2.0.2、11.2.0.3のより新しいバージョンがより良く動作することを期待しています。

適応カーソル共有のインとアウトの議論は、このフォーラムの範囲外である可能性があり、しかし、それの良い議論についてはこちらを参照してください。 http://blogs.oracle.com/optimizer/entry/update_on_adaptive_cursor_sharing

また、そのブログに検索機能を使用同じ主題の他の投稿だけでなく、他の多くのオプティマイザのトピックにも対応しています。そのブログは実際にOracleのオプティマイザ開発チームによって作成されているので、優れたリソースです。

+0

フルバージョンは11.2.0.1です。あなたが言及したリンクを確認し、同じテストをOracle 10gでも実行します。この問題は、11gにアップグレードした後で初めて発生しました。 –

2

これは古くなったテーブル統計のケースだと思います。 Adaptive Cursorを脇に置くと、オラクルはオプティマイザの観点から、新しい統計が収集されたときにのみ新しい行を表示します。この後、しばらくして新しい計画が生成されます。

このクエリでは、使用したヒントは無害です。通常、ヒントではなく根本的な問題を解決するのが最善です。第1の行ヒントは、意図を表現しながらも働いている可能性があります。

2

ここでのように失効した統計を使用しているため、クエリが非効率的な場合は、通常、統計を再解析する必要があります。

あなたは一般的に統計が古くなっていることを検出すると、唯一の適切なオブジェクトのためにそれらをregatherするために、Oracleに頼ることができますが、テーブルの監視は変化の高い数が統計以来発生しているかどうかを確認するためにオンにされている場合にもDBA_TAB_MODIFICATIONSを確認することができます最後に集まった。

後で処理するために大量のデータをステージングするテーブルなど、頻繁に頻繁に変動するテーブルがある場合は、テーブルの統計情報を削除してロックし、最適化ツールを使用することをお勧めします返される行の推定値の動的サンプリング。