2

楽しみのために、私は今日Toadで組み込みのOracle用オプティマイザーで遊んでいます。それが示唆する最適化の1つは次のとおりです

AND emp.pay_type = NVL('FT', UID)

それ以外の

AND emp.pay_type = 'FT'

私はここで何が起こっているのか混乱しています。そのため、なぜこれがパフォーマンスを向上させるのかについても混乱しています。FTはSQLクエリ内の文字列リテラルであり、したがってNULLになることはないので、なぜこれが違いを生むのでしょうか。フィールド上の既存のインデックスと関係があると思いますが、Oracleのドキュメントで何も見つかりません。

4

3 に答える 3

4

それは奇妙なアドバイスです。NVL関数は次のように機能します。

NVL(exp1, val1)

'exp1'がnullでない場合は、返されます。それ以外の場合は、「val1」が返されます。

この例の「FT」はNULLにすることはできないため、NVL関数を使用するメリットはなく、パフォーマンスがわずかに低下します(少なくとも、オプティマイザーがNVLが冗長であることを確認するには、オプティマイザーが機能しない場合は実行ペナルティが発生する可能性があります)。 NVLは冗長です)。

条件が読み取られた場合:

AND emp.pay_type = NVL( "FT"、UID)

そうすれば、メリットがあるかもしれません。ここでは、区切られた識別子(二重引用符で囲まれた列名)があり、列の値はおそらくNULLである可能性があります。NVL呼び出しは、「FT」がNULLUIDがNULLの場合にのみNULLが返されることを保証します。もちろん、UIDは通常の識別子です。

条件が次のようになっている場合は意味があります。

AND emp.pay_type = NVL(UID, 'FT')

これで、UID値がNULLの場合、デフォルト値「FT」が対応するpay_typeとして使用されます。

于 2010-09-27T21:26:35.977 に答える
3

私はヒキガエルの「最適化の提案」を巨大な塩の粒で受け止めます。私はそれらを最適化の「ショットガン」メソッドと呼んでいます-ターゲットにたくさんの異なるビットを撃ち、それらのどれがヒットするかを確認します、どういうわけか:)

とにかく、間の違い

AND emp.pay_type = NVL('FT', UID)

AND emp.pay_type = 'FT'

2番目のケースでは、オプティマイザーは列のヒストグラム統計を使用して(収集されている場合)、一致する行の数のより正確な推定値を取得できます。ただし、NVLが使用されている場合、オプティマイザーは(私が思うに)NVLを無視できることを検出しないため、ヒストグラムで値をチェックしません。

これは、私が一般的に使用する最適化方法ではありません。クエリの実行パスを制御するためのより良い方法があります(たとえば、ヒント)。NVL([literal value],[anything])特に、この方法は、CBOを改善して、のように冗長なコードを探して最適化すると失敗します[literal value]

于 2010-09-28T04:57:56.960 に答える
1

OracleのExplainPlanは、2つのクエリについて何を教えてくれますか?

于 2010-09-27T21:47:13.883 に答える