2009-06-25 32 views
2

私はリファクタリングを実行するために取り組んでいるという幾分面倒なクエリを継承しました。どのようにしてインラインビューをプッシュすると、クエリが遅くなる可能性がありますか?

私が個人的な好みのためにしたことの1つは、ANSI-99のすべての結合構文を「内部結合」および「左外部結合」文から問合せの述語に変更することでした。私は非常に奇妙なものが2つあることに気付きました。

  1. 「INNER JOIN ...」構文からの結合を変更すると、EXPLAIN PLANプランが変更されました。 ANSI 99の構文では、oracleは結合されていた列の全表スキャンを実行しました。結合構文を変更すると、述語プッシュが行われます。なぜ、結合構文がExplainプランを変更するのですか?
  2. インラインビューをプッシュする述部によって、実際にはクエリが大幅に遅くなりました。約3秒で(結合を変更する前に)実行されていたクエリ。今は9秒かかります。正直言って、私は計画を説明することについてかなり新しいので、クエリの再構成が別の理由でそれを遅らせる可能性は全くあります。しかし、最終的に私の質問は次のようになります。「述語が索引付き列を押してクエリを大幅に遅くすることは可能ですか?そうなら、なぜですか?

回答してくれてありがとう、と私の謝罪これは非常に明確でない場合は...

+0

変更前のクエリと変更後のクエリを投稿してください。クエリの意味が変更された場合(またはオプティマイザが利用できる情報を追加/削除する場合)かなりの計画。 –

答えて

3

それはそう、実質的にクエリを遅くするインデックス列にプッシュする述語のために可能ですか?もしそうなら、なぜですか?

確かです。

通常、述語プッシュは、HASH JOINの代わりにNESTED LOOPSをオプティマイザに選択させます。

条件が選択的でない場合、これは遅くなる可能性があります。

このクエリ

SELECT * 
FROM table1, t1 
     (
     SELECT /*+ NO_PUSH_PRED */ 
       * 
     FROM table2 t2 
     WHERE t2.col1 = :value1 
     ) t2o 
WHERE t2o.col2 = t1.col2 

はおそらくtable1の内容上のハッシュ表を作成し、このハッシュテーブルに対してビューで返される行(またはその逆)を調べます。

このクエリ:それは定義されていた場合

SELECT * 
FROM table1, t1 
     (
     SELECT /*+ PUSH_PRED */ 
       * 
     FROM table2 t2 
     WHERE t2.col1 = :value1 
     ) t2o 
WHERE t2o.col2 = t1.col2 

(t2.col1, t2.col2)NESTED LOOPSとインデックスを使用します。

col2table2で選択されている場合は後者が効率的で、そうでない場合は効率が低下します。

私の知る限りの推測は、まさにあなたの場合に起こっていることです。

あなたのクエリと実行計画を投稿すると、私はおそらくもっと伝えることができます。

+0

ありがとうございました。述語のプッシュが使用されているかどうかにかかわらず、単に結合の構文を変更すると変更されるのは一般的ですか? – jnt30

+0

@ jnt30:オラクルのオプティマイザは予測不能な方法で動作します。私は最悪の場合に10秒以上実行されるすべてのクエリを個人的に概説します。 – Quassnoi

+0

@Quassnoi:ありがとう、ありがとう。私はあなたがこれについていくつかのあなたの記事を見たことを知っている、私はそれらを見て、それをすべて理解しようとします。私は主にJava開発者でしたので、このうちのいくつかは私にとって非常に新しいものです。私はあなたの質問に答える時間を感謝します。 – jnt30

関連する問題