I have the below query :
select databasename
from somedb.dbo.bigtable l where databasename ='someval' and source <>'kt'
and not exists(select 1 from dbo.smalltable c where c.source=l.source)
The above query completes in three seconds.
If the above query returns any value, we want the stored procedure to EXIT,so I rewrote it like below:
If Exists(
select databasename
from somedb.dbo.bigtable l where databasename ='someval' and source <>'kt'
and not exists(select 1 from dbo.smalltable c where c.source=l.source)
)
Begin
Raiserror('Source missing',16,1)
Return
End
However this is taking 10 minutes.
I can rewrite the above query like below, which also completes in less than 3 seconds:
select databasename
from somedb.dbo.bigtable l where databasename ='someval' and source <>'kt'
and not exists(select 1 from dbo.smalltable c where c.source=l.source
if @@rowcount >0
Begin
Raiserror('Source missing',16,1)
Return
End
The issue with above rewrite is that the above query is part of bigger stored procedure and it returns multiple result sets. In C#,we iterate through each result set and do some processing.
The above returns an empty result set, so if I go with this approach, I have to change my C# and do deployment again.
So my question is,
why does using just
IF EXISTS
changes the plan to take so much time?
Below are the details which may help you and let me know if you need any details:
- Create table and statistics script to get same plan as mine
- Slow Execution plan
Fast Execution plan
Slow plan using Brentozar Paste the plan
Fast Plan using Brentozar Paste the plan
Note: Both queries are the same (using parameters), the only difference is EXISTS
(I might have made some mistakes while anonymizing though).
The table creation scripts are below:
http://pastebin.com/CgSHeqXc -- small table stats
http://pastebin.com/GUu9KfpS -- big table stats