2016-05-26 19 views
4

私は意見を探しており、おそらく以下に具体的な答えがあります。
この質問は、ストアドプロシージャでは、SQL Serverのバージョン2008 R2 +T-SQL ISNULLここで条件のパフォーマンス

に適用され、私はDATE型のオプションのクエリパラメータを持って、それを@myvar呼び出すことができます。

SELECT A, B, C 
FROM MyTable 
WHERE MyTable.Field1 = ISNULL(@MyVar,MyTable.Field1) 

@myvarがNULLである場合ISNULL(@のMyVar、MyTable.Field1)を行うためのコストはどのようなものです:

ストアドプロシージャは、次のクエリを実行しますか?

IF (@MyVar IS NULL) 
    SELECT A, B, C 
    FROM MyTable 
ELSE 
    SELECT A, B, C 
    FROM MyTable 
    WHERE MyTable.Field1 = @MyVar 

ありがとう:それはのような例を分割した方が良いかどう 私は疑問に思って!

+2

インデックスされた。 –

+0

最後に 'WHERE MyTable.Field1 = @ MyVar'を意味します。 – jarlh

+0

@MarcBなぜそれがインデックスの使用を妨げるのかわかりません – Lamak

答えて

10

よりエレガントなアプローチは次のようになります@JamesZによって提案に基づい

SELECT A, B, C 
FROM MyTable 
WHERE MyTable.Field1 = @MyVar 
    OR @MyVar IS NULL 
OPTION(RECOMPILE) 

編集

(存在する場合)field1にインデックスが使用されるように、option(recompile)を添加。

EDIT2(。それを指摘してくれてありがとうの@YB)

field1のようなものを使用だけでなくnullすることができた場合:これはすでに 'キャッチすべての' クエリの問題を示して

SELECT A, B, C 
    FROM MyTable 
    WHERE MyTable.Field1 = @MyVar 
     OR (@MyVar IS NULL AND MyTable.Field1 IS NULL) 
    OPTION(RECOMPILE) 

を。たとえば、最後のクエリのANDORに置き換えると、さらに別の(理論的な)結果セットが得られる可能性がありますが、それも正しい可能性があります。

+0

を読むことをお勧めします。インデックスはまだ使用されていませんが、読むのは簡単ですが、将来のバグを防ぐために括弧を追加します。 –

+0

@JamesZ、さらに条件が追加された場合は、必ずかっこを追加してください。私はあなたがインデックスについて何を得ているのかよく分かりません。 – HoneyBadger

+0

インデックスの使用に関するコメントには議論があり、 'Field1'がインデックスされている場合、' option(recompile) 'が使われない限り、' @ MyVar'がヌルでなくてもインデックスは使われません。 –

0

最高のパフォーマンスを得るには、@MyVarを必要とする手順とそうでない手順の2つがあります。そうすれば、最初に遭遇するのではなく、それぞれのケースについてクエリプランを得ることができます(parameter sniffing参照)。

値を使用するかどうかによってクライアントの呼び出しが意味を持ちます。

あなたは、コードの重複を懸念している場合は、クエリ

SELECT A, B, C 
    FROM MyTable 

の根性のためviewを追加して、意味をなすの条件でその中から選択します。 それは魔法ではありません。残念ながら、どれもサイズに合っていません。

0

どこField1 is NULL

IF (@MyVar IS NULL) 
    SELECT A, B, C 
    FROM MyTable 
ELSE 
    SELECT A, B, C 
    FROM MyTable 
    WHERE MyTable.Field1 = @MyVar 

一方だろう

SELECT A, B, C 
FROM MyTable 
WHERE MyTable.Field1 = ISNULL(@MyVar,MyTable.Field1) 

がレコードを返しませんので、予めご了承ください。

技術的には元の式を書き換えるための正しいかつ効率的な方法は次のようになります。それができない、あなたがあたり、フィールド計算値に対して `field1`を比較していることから、インデックスの使用を防ぐん

SELECT A, B, C 
FROM MyTable 
WHERE @MyVar IS NULL AND MyTable.Field1 IS NOT NULL 
UNION ALL 
SELECT A, B, C 
FROM MyTable 
WHERE @MyVar IS NOT NULL AND MyTable.Field1 = @MyVar