We usually encountered the case that select result that if not input argument or a column equals the argument, the expression like below comes to our brains:
WHERE @Arg IS NULL OR Name = @Arg
Almost all programming languages will ignore the second condition if @Arg is set to NULL. However, I find it was being executed in SQL Server very slowly and looked like the second condition always be went through.
Anyone could give me help?
This is not a question of boolean short circuit (which is not guaranteed in SQL, see On SQL Server boolean operator short-circuit) but a problem of compilation. SQL Server will have to compile a query plan for you and the plan will have to work for any value of
@Arg. This requirement will eliminate many possible optimizations (eg. if you have an index onNameit cannot be used), resulting in unnecessarily slow queries.This pattern is repeated again and again, typically in search forms, and the recommendation is to create different queries. The underlying problem is an incorrect API design that uses the same call to do different things (search by Name, search by ID etc).
The article linked by Martin goes to great length explaining pros and cons of various approaches. Erland’s advice is more nuanced (use IF for simple cases, dynamic SQL for complex cases) but it boils down to the same thing: use different queries for each case, whether hard coded (
IFs) or code-generated (dynamic SQL).