2017-09-27 16 views
0

私はたくさんのストアドプロシージャを開発していますが、その大部分にはwhere節があります。私に関する何ストアドプロシージャここでは多くのパラメータを含むステートメント

WHERE 
    (CE.EnquiryDate >= @StartDate or @StartDate is null) and 
    (CE.EnquiryDate <= @EndDate or @EndDate is null) and 
    (CE.ClientID = @ClientID or @ClientID is null) 

パフォーマンスがあると計画がSPの最初の実行時にキャッシュされている場合のClientIDが、それは明らかに起こっている渡されたときにのみ、トラック、すなわちダウン潜在的原因の問題が発生した実行計画ClientIDが渡されず、StartDateとEndDateが異なる場合とは異なります。

複数のストアドプロシージャに分割したり、OPTION (RECOMPILE)を使用して、実行ごとに新しい計画を立てる方が良いでしょうか?最良のアプローチが開発の初期段階にあるかどうかは不思議です。

+0

を回避OR ...についての詳細はhttps://en.wikipedia.org/wiki/Boolean_algebraを参照してください。 –

+0

Gordonに感謝しますが、動的SQLを行うよりもspの下に追加するだけで同じ効果がありませんか? – Philip

+0

。 。それは試してみる価値があります。おそらく、SQL Serverでは、パラメータを使用して 'または'節を使用して 'where'節を最適化するほうが賢明になりました。 –

答えて

2

この質問の標準的な扱いは、Erland SommarskogのDynamic Search Conditions in T-SQLです。テクニックとトレードオフの詳細については、それをお読みください。

OPTION RECOMPILEを使用している場合、SQL 2008 SQL Serverはこの種のクエリに対して最適化します。ヌル・パラメーターに対応する述部は、コンパイル中に照会から除去されます。ですから、OPTION RECOMPILEは私のここでのデフォルトですが、いくつかの検索パターンがある場合は、安価にする必要があります。以下のような

何か:

IF (@StartDate is not null and @ClientId is not null) 
BEGIN 

    SELECT * 
    FROM T 
    WHERE 
     (CE.EnquiryDate >= @StartDate) and 
     (CE.EnquiryDate <= @EndDate or @EndDate is null) and 
     (CE.ClientID = @ClientID) 

    RETURN 
END 


SELECT * 
FROM T 
WHERE 
    (CE.EnquiryDate >= @StartDate or @StartDate is null) and 
    (CE.EnquiryDate <= @EndDate or @EndDate is null) and 
    (CE.ClientID = @ClientID or @ClientID is null) 
WITH (OPTION RECOMPILE) 
+0

あなたのお返事ありがとうDavid、ありがとうございます。最初の質問に記載されているものに基づいて、「特殊なケース」を取り巻く例を挙げてください。乾杯。 – Philip

+0

@James彼がしました。それは最初のifステートメントの目的です - それは "特殊なケース"です。 – SMor

+0

@ Jamesのコメントに応じて例を追加しました。 –

0

はこれを試してみてください:

WHERE 
    (CE.EnquiryDate >= ISNULL(@StartDate,CE.EnquiryDate)) and 
    (CE.EnquiryDate <= ISNULL(@EndDate,CE.EnquiryDate)) and 
    (CE.ClientID = ISNULL(@ClientID,CE.ClientID)) 

これが原因で、 "< ="、 "> =" と "=" の使用することができます:<」で作業していません"または"> "を入力します。

目標はOR演算子です...魔女はとても遅いです。実行計画を参照してください。

あなたは `各実行のための最適な実行計画を確実にするために、`オプション(再コンパイル)で、動的SQLを使用することができます

X OR Y = NOT (NOT X AND NOT Y) 
+0

良くないです。どちらのクエリでもテーブルスキャンが必要で、ISNULL _also_では、各行に対してISNULL(@ param、col)式を評価する必要があります。ここで問題となるのは、すべての基準の組み合わせに対して同じ計画を使用するか、検索基準のさまざまな組み合わせに対して異なる計画を使用する方法を見つけるかです。 –

+0

Microsoftから聞いてよかった^^ RECOMPILEはこの場合には賢明ですが、システム化されて使用される傾向があります。 – clementakis

関連する問題