Параметризованный SQL и NULL работают медленно - PullRequest
2 голосов
/ 29 марта 2011

Я звоню какой-нибудь параметризованный sql из .net.Я не уверен, почему, но SQL работает довольно медленно при проверке, если параметр имеет значение NULL, по сравнению с тем, когда он не включен:

Так вот:

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-профилировщика длительность верхнего запроса на 1 миллион строк составляет 175, а его чтения - 3720, а продолжительность второго запроса - 1 и только 3 чтения.

Почему такая разницаи как это можно улучшить?

Ответы [ 2 ]

5 голосов
/ 29 марта 2011

Предложение ИЛИ НЕДОПУСТИМО, поэтому в используемом плане есть сканирование, а не поиск, как во втором

Попробуйте это: 2 стремится

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

Примечание: вам не нужна подсказка NOLOCK. Или 1=1

1 голос
/ 29 марта 2011

Невозможно сделать это в SEEK, если @id равен NULL, поэтому он всегда будет 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Подсказка, если она не переписана строго.

...