2

.netからパラメータ化されたSQLを呼び出しています。理由はわかりませんが、パラメーターが含まれていない場合と比較して、パラメーターがNULLであるかどうかを確認すると、SQLの実行が非常に遅くなります。

したがって、この:

exec sp_executesql N'
 SELECT [id]
 FROM [tblAddress] (nolock)
 WHERE 1 = 1
 AND ([id] = @id OR @id  IS NULL)

',N'@id int',
@id=4395

これよりも速く実行されます:

exec sp_executesql N'
 SELECT [id]
 FROM [tblAddress] (nolock)
 WHERE 1 = 1
 AND ([id] = @id)

',N'@id int',
@id=4395

SQLプロファイラーを実行すると、100万行を超える上位のクエリの期間は175で、読み取りは3720ですが、2番目のクエリの期間は1で、読み取りは3つだけです。

なぜそのような違いがあり、どのようにそれを改善できるのでしょうか?

4

2 に答える 2

5

OR句はSARGABLEではないため、使用されるプランにはスキャンがあり、2番目のようなシークではありません

これを試してください:2シーク

SELECT [id]
 FROM [tblAddress]
 WHERE [id] = @id
UNION ALL
SELECT [id]
 FROM [tblAddress] 
 WHERE @id IS NULL)

注:NOLOCKヒントは必要ありません。または1=1

于 2011-03-29T05:01:25.830 に答える
1

@idがNULLの場合、SEEKに到達する方法はないため、常にSCANになり、常に低速になります([tblAddress]の行数によって異なります。これに対抗するには、量を制限することをお勧めします)。 TOP(N)句を指定することにより、クエリによって返される結果の数。

だから私がすることは:

IF @id IS NOT NULL
BEGIN
    SELECT [id]
      FROM [tblAddress]
     WHERE [id] = @id
END
ELSE
BEGIN
    SELECT TOP(20) [id] FROM [tblAddress] 
END

また、厳密に必要とされない限り、NOLOCKヒントは使用しません。

于 2011-03-29T05:26:59.327 に答える