キャッシュされている実行計画について心配するのは当然です。
マーティンは、計画がキャッシュされ、最初に実行されたときにロジックの特定のブランチに対して最適化されることを示す良い例を示しています。 異なるパラメータでストアドプロシージャ(sproc)を呼び出しても、最初の実行後にそのプランが再利用され、実行フローが別のブランチを選択します。 これは非常に悪く、パフォーマンスを低下させます。私はこれが何度も起こるのを見ており、根本的な原因を見つけるのにしばらく時間がかかります。
「パラメータスニッフィング」と呼ばれており、調査する価値があります。
私がアドバイスしていない共通の解決策は、あなたのsprocをいくつかの小さなものに分割することです。 sprocの内部でsprocを呼び出すと、内部のsprocはそれに渡されるパラメータに最適化された実行計画を取得します。
sprocをいくつかの小さなものに分割するのは、正当な理由がない場合(良い理由はモジュール性です)は醜い回避策です。 Martinは、スキーマに変更を導入することによってステートメントを再コンパイルすることが可能であることを示しています。 私は、ステートメントの最後にOPTION(RECOMPILE)を使用します。これは、現在の値すべての変数を考慮して、ステートメントの再コンパイルを実行するようオプティマイザに指示します。パラメータだけでなく、ローカル変数も考慮され、良い計画と悪い計画の違いがあります。
パラメータに応じて別のwhere句を使用してクエリを作成することに戻ってください。下側があれば影響を与えることができた(それはしかし声明の時点までキャッシングは影響しません。)この文の実行計画がキャッシュされないことである
WHERE
(@parameter1 is null or col1 = @parameter1 )
AND
(@parameter2 is null or col2 = @parameter2 )
...
OPTION (RECOMPILE)
:私は、次のパターンを使用しますコンパイル時間が考慮されるべきであるので、sprocは何度も実行される。プロダクション品質のデータを使ってテストを実行すると、問題がある場合に回答が得られます。
読み取り可能でエレガントなsprocsをコード化でき、不適切な足にオプティマイザを設定できないという点があります。
さらに注意する必要があるもう1つの選択肢は、sprocレベル(ステートメントレベルとは対照的に)レベルがそれほど細かくなく、さらに重要なことに、ローカル変数の値を考慮しないで、最適化するとき。 http://www.sommarskog.se/dyn-search-2005.html http://sqlinthewild.co.za/index.php/2009/03/19/catch-all-queries/何だろう `IF ... ELSE
で
詳しい情報... .'(または 'CASE')には正確に?場合によっては、条件をパラメータに抽象化することが可能であり、より効率的です。 procごとに1つの実行計画があるため、条件付きロジックによって不均一なパフォーマンスが生じる可能性があります。 –