0

次の2つのSQLステートメントがあります

最初の1つ:

IF(@User_Id IS NULL)  
BEGIN  
      SELECT *
      FROM [UserTable]
END  
ELSE           
BEGIN                  
      SELECT *
   FROM  [UserTable] AS u
   WHERE  u.[Id] = @User_Id                  
END 

二つ目:

SELECT  *
FROM [UserTable] AS u
WHERE (@User_Id IS NULL OR u.[Id] = @User_Id)

これらのクエリは両方とも、独自のストアドプロシージャにラップされます。IFステートメントがSQLで多くの再コンパイルを引き起こしているのではないかと思います。IFステートメントの各部分を独自のストアドプロシージャに分離するか、IFステートメント全体をWHERE句に置き換える(上記の2番目のSQLステートメントで示した)ことに直面しています。

私の質問は、パフォーマンスの観点から2つのステートメントの違いは何ですか、SQLは各ステートメントをどのように処理するのでしょうか。

ありがとう。

4

1 に答える 1

0

どちらのソリューションでも、同じ数のコンパイルが生成されます。

クエリオプティマイザの最初のソリューションは、2つの異なるクエリのそれぞれに最適なプランを自由に考え出すことができます。最初のクエリ(IFのNULLブランチ)は最適化できるほど多くはありませんが、2番目のクエリ(IDのNOT NULLブランチ)は、Id列にインデックスが存在する場合に最適化できます。

しかし、2番目の解決策は最適化の災害です。パラメーターの値に関係なく、オプティマイザーはパラメーターの任意の@User_Id値に対して機能する計画を考え出す必要があります。そのため、の値に関係なく、プランは常に次善のテーブルスキャンを使用します。この問題を回避する方法はありません。これは、一部の人が考えるようなパラメータスニッフィングではありません。プランの正しさです。プラン生成時の値がNULLでない場合でも、パラメーターがNULLの場合でもプランは機能する必要があるため、のインデックスを使用できません。@User_IdId

常に、常に、常に、明示的な。を含む最初の形式を使用しIFます。

于 2010-11-04T18:05:59.960 に答える