ユージュアル・サスペクツ:
- アドホックの定数、コードのパラメーター
- コード内のデータ型の不一致
- パラメータスニッフィング
ポイント1:オプティマイザは定数の最適な計画を選択できます。
定数を変更する=計画を変更する。パラメータ化されたプレンは復活可能です
ポイント2では
、nvarcharパラメータと比較したvarchar列などのデータ型の優先順位のため、暗黙的な変換が導入されます
ポイント3:パラメーターマスキングまたはOPTIMIZE FOR UNKNOWNを使用する
編集:テストするには、ストアドプロシージャを実行し、sp_updatestatsを実行して、再度実行します。これは、キャッシュされたプランを無効にし、プランキャッシュをクリアするよりも優れています
編集:jcolebrandのコメントの後
いくつかの方法でスニッフィングを無効にすることができます。メイン3は
- 再コンパイル。これはばかげたIMOです。
- 不明の最適化(sic)
- パラメータマスキング
パラメータマスキング:
DECLARE @MaskedParam varchar(10)
SELECT @MaskedParam = @SignaureParam
SELECT...WHERE column = @MaskedParam
マスキングとOPTIMIZEヒントの効果は同じです(理由はさまざまです)。つまり、オプティマイザは統計とデータ分布を使用する必要があります(注:まだMark Storey-Smithによるテスト中)、独自のメリットでパラメータを評価しますか? 彼らが最後に呼んだものではなく、オプティマイザは再コンパイルすることもしないこともできます。SQL Server 2005はステートメントレベルの再コンパイルを追加したので、影響は少なくなりました
さて、なぜ「スニッフィング」パラメータを持つプランが「マスクされた」/「不明な」パラメータと比較して「スティッキー」であるのか、私にはわかりません。
SQL Server 2000以降、最も単純なコードを除いて、すべてパラメーターマスキングを使用しています。より複雑なコードで発生する可能性があることを指摘しました。そして、私の古い仕事で、私は計画パラメーターのデフォルトを変更できるいくつかのレポートプロシージャを持っています。「カーゴカルト」のアプローチはサポートコールよりも簡単だと思います。
チャットの後、2011年10月12日2を編集
パラメータマスキングとOPTIMIZE FOR UNKNOWNは、私の知る限り同じ効果があります
。ヒントはマスキングよりもきれいですが、SQL Server 2008で追加されました。
パラメータのスニッフィングはコンパイル時に行われます。
WITH RECOMPILEは、実行ごとに新しいプランを生成します。つまり、デフォルトの選択が適切でないと、計画に影響が出ます。私の最後の仕事で、これをいくつかのレポートコードで簡単に示すことができました。パラメーターのデフォルトを変更すると、提供されたパラメーターに関係なく計画が変更されました。
このMS Connectの記事は興味深いです:ストアドプロシージャ内でのインデックスの使用が最適ではありません(以下のSOの回答の1つで言及されています)
- ボブ・ボーケミンもそれについて言及している
未解決の問題
SOからのリンク:
WHERE
句の変数を参照していますか?