There is a report whose query is using isnull in the where clause and it’s causing some performance issues.
Here is a very simplified example.
http://www.sqlfiddle.com/#!6/79759/11
The query is using a multi-valued parameter, usually just returning one or two values. (I’ve tried to replicate the SSRS multi-value param using a table variable in sqlfiddle)
select
isnull(descrL,descr) as division,
product
from Upper
left join Lower on product = productL
where isnull(DescrL,Descr) in (@params)
There is an Upper division that has all the products. Some of the products exist on a child division. If it exists in the lower division, that is the division that should be shown.
The company parameter can accept the upper division, lower division, or both.
Any ideas on how the query can be changed for better performance?
This would be very performant. If the match is found in the top select, it should be suppressed in the bottom select since it’s a union instead of a union all. Notice the like instead of in. If you do an in there is just no way to use an index on DescrL or Descr to find the results. If you do a like, indexes are used fine. You may have to adjust your application logic to make that work.
If you can’t do that, then there is this solution. You’ll have to add fn_split to your db. http://msdn.microsoft.com/en-us/library/aa496058(v=sql.80).aspx
If you really want to eke out the very last bit of performance you can declare a table variable and only run the fn_split once in order to populate the table variable, and then make the two joins be to the table variable. So here you are also taking advantage of the index on the columns, which is the main thing you need to make the query faster. Always do ‘include actual execution plan’ in sql server when you run it, and look at the results and make sure you’re seeing index seeks instead of table scans.
EDIT: I went over to your sqlfiddle link. Didn’t see it earlier. This works. The union by itself won’t suppress dupes, since you are also selecting the division, sorry. So you have to use a not in, or as I prefer, a left outer where null.