I'm writing a general search Stored Procedure to search in a table based on many filters which user can select in the UI (using MS-SQL 2008).
Here is ther simplified version:
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)
It seems that if I pass NULL to @Age there'll be no performance cost. But, when I'm testing with huge amount of data, I have a great perfomance lost!
Here is the queries which are the same logicaly but VERY different practically:
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
Did is miss a point?
I know that SQL engine finds the best match for indexes, and ... (before running the query),but it's obvious that: @FirstName IS NULL
and there's no need to analyse anything.
I've also tested ISNULL
function in the query (the same result).