Я пишу общую хранимую процедуру поиска для поиска в таблице на основе множества фильтров, которые пользователь может выбрать в пользовательском интерфейсе (используя MS-SQL 2008).
Вот упрощенная версия:
CREATE PROCEDURE SearchAll
@FirstName NVARCHAR(MAX) = NULL,
@LastName NVARCHAR(MAX) = NULL,
@Age INT = NULL
AS
SELECT *
FROM persons
WHERE
(@FirstName IS NULL OR FirstName = @firstname)
AND (@LastName IS NULL OR LastName = @LastName)
AND (@Age IS NULL OR Age = @Age)
Похоже, что если я передам NULL @Age, производительность не снизится.Но, когда я тестирую с огромным количеством данных, я теряю отличную производительность!
Вот запросы, которые одинаковы по логике, но ОЧЕНЬ отличаются практически:
DECLARE @FirstName NVARCHAR(MAX) = NULL
DECLARE @Age INT = 23
------------First slow------------
SELECT *
FROM persons
WHERE
(@FirstName IS NULL OR FirstName = @firstname)
AND (@Age IS NULL OR Age = @Age)
------------Very fast------------
SELECT *
FROM persons
WHERE
Age = @Age
Сделалпропустить точку?
Я знаю, что механизм SQL находит лучшее соответствие для индексов и ... (до выполнения запроса), но очевидно, что: @FirstName IS NULL
и анализировать что-либо не нужно.
Я также протестировал ISNULL
функцию в запросе (тот же результат).