2

私はパフォーマンスを向上させるためにリファクタリングに取り組んでいるやや厄介なクエリを継承しました。

このプロセス中に、私が個人的な好みで行ったことの 1 つは、ANSI-99 結合構文のすべてを「内部結合」および「左外部結合」ステートメントからクエリの述語に変更することでした。2 つの非常に奇妙なことに気付きました。説明をいただければ幸いです。

  1. 「INNER JOIN...」構文から結合を変更すると、説明計画が変更されました。ANSI 99 構文を使用すると、Oracle は結合される列に対して全表スキャンを実行しました。結合構文を変更した後、述語のプッシュが行われるようになりました。結合構文によって説明計画が変更されるのはなぜですか?
  2. インライン ビューにプレディケートをプッシュすると、実際には、クエリが非常に大幅に遅くなります。(結合を変更する前に) 約 3 秒で実行されていたクエリ。現在、9秒かかります。正直なところ、私は説明計画を読むのはかなり初めてなので、クエリの再構築によって別の理由で速度が低下した可能性は十分にあります。しかし、最終的に私の質問は次のとおりです。

返信ありがとうございます。これが明確でない場合は申し訳ありません...

4

1 に答える 1

3

インデックス付きの列を述語でプッシュすると、クエリの速度が大幅に低下する可能性はありますか?もしそうなら、なぜですか?

もちろんそうだ。

原則として、述語プッシュにより、オプティマイザーはのNESTED LOOPS代わりに選択しますHASH JOIN

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

このクエリ

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

定義されている場合は、NESTED LOOPSとのインデックスを使用します。(t2.col1, t2.col2)

後者は、col2が選択的である場合はより効率的でtable2あり、そうでない場合は効率が低くなります。

私の知識に基づいた推測では、それがまさにあなたのケースで起こっていることです。

あなたがあなたの質問と実行計画を投稿するならば、私はおそらくもっと話すことができるでしょう。

于 2009-06-25T15:35:44.447 に答える