I have an SQL query that takes these parameters:
@SearchFor nvarchar(200) = null
,@SearchInLat Decimal(18,15) = null
,@SearchInLng Decimal(18,15) = null
,@SearchActivity int = null
,@SearchOffers bit = null
,@StartRow int
,@EndRow int
The variables @SearchFor, @SearchActivity, @SearchOffers can be either null or not null. @SearchInLat and @SearchInLng must both null, or both have values.
I’m not going to post the whole query as its boring and hard to read, but the WHERE clause is shaped like this:
( -- filter by activity --
(@SearchActivity IS NULL)
OR (@SearchActivity = Activities.ActivityID)
)
AND ( -- filter by Location --
(@SearchInLat is NULL AND @SearchInLng is NULL)
OR ( ... )
)
AND ( -- filter by activity --
@SearchActivity is NULL
OR ( ... )
)
AND ( -- filter by has offers --
@SearchOffers is NULL
OR ( ... )
)
AND (
... -- more stuff
)
I have read that this is a bad way to structure a query – that SqlServer has trouble working out an efficient execution plan with lots of clauses like this, so I’m looking for other ways to do it.
I see two ways of doing this:
- Construct the query as a string in my client application, so that the
WHEREclause only contains filters for the relevant parameters. The problem with this is it means not accessing the database through stored procedures, as everything else is at the moment. - Change the stored procedure so that it examines which arguments are null, and executes child procedures depending on which arguments it is passed. The problem here is that it would mean repeating myself a lot in the definition of the procs, and thus be harder to maintain.
What should I do? Or should I just keep on as I am currently doing? I have OPTION (RECOMPILE) set for the procedures, but I’ve heard that this doesn’t work right in Server 2005. Also, I plan to add more parameters to this proc, so I want to make sure whatever solution I have is fairly scaleable.
The answer is to use DynamicSQL (be it in the client, or in an SP using
sp_executesql), but the reason why is long, so here’s a link…Dynamic Search Conditions in T-SQL
A very short version is that one-size does not fit all. And as the optimiser creates one plan for one query, it’s slow. So the solution is to continue using parameterised queries (for execution plan caching), but to have many queries, for the different types of search that can happen.