ひどく実行するストアドプロシージャがあります。変数を宣言するときは、その値を設定してから、ステートメントの実行に1時間以上かかるwhere句で使用します。where句の変数をハードコーディングすると、1秒未満で実行されます。
私は実行計画を通してそれの何が悪いのかを調べ始めました。UNIONと共通テーブル式を使用するビューから値を選択するため、いくつかの宣言された変数を渡そうとすると、実行プランはいくつかのハッシュ一致を作成するように見えます。
/*************ストアドプロシージャの開始***************/
手順の作成GetFruit
@ColorId bigint、
@SeasionId bigint
再コンパイルあり
なので
始める
選択する
名前
から
[Apple_View] A/*これは下のビューです*/
インナージョイント[フルーツ]F
オン(F.ColorId = @ColorId
AND A.FruitId = F.FruitId)
どこ
(A.ColorId = @ColorId
と
A.SeasonId = @SeasonId)
終わり
/*************ストアドプロシージャの終了***************/
/*************ビューの開始***************/
果物付き(FruitId、ColorId、SeasonId)AS
((
-アンカーメンバー
選択する
F.FruitId
、F.ColorId
、F.SeasonId
から
(((
距離を選択
EF.FruitId
、EF.ColorId
、EF.SeasonId
、EF.ParentFruitId
から
エキゾチックフルーツEF
インナージョインフルーツFR
ON FR.FruitId = EF.FruitId
連合
距離を選択
SF.FruitId
、SF.ColorId
、SF.SeasonId
、SF.ParentFruitId
から
StinkyFruit SF
インナージョインフルーツFR
ON FR.FruitId = SF.FruitId
連合
距離を選択
CF.FruitId
、CF.ColorId
、CF.SeasonId
、CF.ParentFruitId
から
CrazyFruit CF
インナージョインフルーツFR
ON FR.FruitId = CF.FruitId
))f
ユニオンオール
-再帰的な親の果実
選択する
FS.FruitId
、FS.ColorId
、FS.SeasonId
、FS.ParentFruitId
から
フルーツFS
内部結合MasterFruitMF
ONMF。[ParentFruitId]=fs。[FruitId]
)。
距離を選択
FS.FruitId
、FS.ColorId
、FS.SeasonId
から
フルーツFS
/*************ビューの終わり***************/
/*実行するには*/
EXEC GetFruit 1,3
設定値を使用してストアドプロシージャを実行すると、1時間以上かかります。これが、実行プランです。

DECLARE値とSET値を削除してストアドプロシージャを実行し、Where句を次のステートメントに設定すると、1秒未満で実行され、実行プランは次のようになります。
WHERE(A.ColorId = 1 AND A.SeasonId = 3)

最初の変数がハッシュセットを使用しているのに対し、ハードコードされた変数がどのようにインデックスを使用しているかに注目してください。何故ですか?where句のハードコードされた値が宣言された変数と異なるのはなぜですか?
-------これは@user1166147の助けを借りて最終的に実行されたものです------
sp_executesqlを使用するようにストアドプロシージャを変更しました。
手順の作成GetFruit
@ColorId bigint、
@SeasionId bigint
再コンパイルあり
なので
始める
DECLARE @SelectString nvarchar(max)
SET @SelectString = N'SELECT
名前
から
[Apple_View] A/*これは下のビューです*/
インナージョイント[フルーツ]F
オン(F.ColorId = @ColorId
AND A.FruitId = F.FruitId)
どこ
(A.ColorId ='+ CONVERT(NVARCHAR(MAX)、@ColorId)+'
と
A.SeasonId ='+ CONVERT(NVARCHAR(MAX)、@SeasonId)+') '
EXEC sp_executesql @SelectString
終わり