Following on from my last question Sql Server query performance, and discovering that my method of allowing optional parameters in a search query is sub optimal, does anyone
Ok, here we go
OPTION (RECOMPILE)
is a must - otherwise the first query plan is being reused, regardless how the parameters match. Sorry, no real way to do that better.
Besides that - no, sorry. Dynamic SQL can get more efficient (by avoiding the IS NULL alternatives), but you basically have it nailed down if that is not possible.
With Dynamic SQL you basically do not have aline for HP.phonenumber if the HomePhone variable is null ;)
In your case, the different queries would use the different indexes.
You should define a set of indexes you want to use and write an individual query for each set, replacing OR
on indexed fields with UNION ALL
:
SELECT *
FROM tables
WHERE A = @ID
AND (c.Surname = @Surname or @Surname IS NULL)
AND (HP.phonenumber = @Homphone or @Homephone IS NULL)
AND (MOB.phonenumber = @Mobile or @Mobile IS NULL)
UNION ALL
SELECT *
FROM tables
WHERE @ID IS NULL
AND c.Surname = @Surname
AND (HP.phonenumber = @Homphone or @Homephone IS NULL)
AND (MOB.phonenumber = @Mobile or @Mobile IS NULL)
UNION ALL
SELECT *
FROM tables
WHERE @ID IS NULL
AND @Surname IS NULL
AND (HP.phonenumber = @Homphone or @Homephone IS NULL)
AND (MOB.phonenumber = @Mobile or @Mobile IS NULL)
There is no "one size fits all" query approach for this, there are subtle performance implications in how you do this. If you would like to go beyond just making the query return the proper answer, no matter how slow it is, look at this article: Dynamic Search Conditions in T-SQL by Erland Sommarskog. It covers every method and gives PROs and Cons of each method in great detail.
If you can determine a min and a max possible range for your search column, and the search column is NOT NULL, then you can do better than the (@Search IS NULL OR Col=@Search), see this area of the above linked article. However you should read the entire article, there are so many variations that depend on your situation, you really need to learn multiple approaches and when to use them.
Also see this other recent answer: SQL Server 2008 - Conditional Query