(SQL Server 2012 being used)
I found some topics on query optimization, and comparing EXISTS to COUNT, but I couldn't find this exact problem.
I have a query that looks something like this:
select * from
tblAccount as acc
join tblUser as user on acc.AccountId = user.AccountId
join tblAddress as addr on acc.AccountId = addr.AccountId
... **a few more joins**
where acc.AccountId in (
select * accountid from
(select accountid, count(*) from tblUser
where flag = 1
group by accountId) as tbl where c != 1
This query runs in an instant (although the db is quite big, around 70Gb).
When I wrap the query in an EXISTS as in:
if exists
(
**Exact same query as above**
)
begin
RAISERROR('Account found without exactly one flagged user.', 16, 1);
end
else
begin
print 'test passed.'
end
Suddenly the query takes about 5-6 seconds to complete. I've tried specifying IF EXISTS (SELECT TOP 1 FROM... and also tried NOT EXISTS (which was even slower). But neither work to speed this up.
If the normal select query completes basically instantly, then does anyone know why wrapping it in the EXISTS causes so much extra computation? And/or anyone have any ideas to work around this (I'm just trying to throw an error if any records are found at all by the original query).
Thanks!
Did you try running the original query with TOP 1? most likely it will be just as slow.
Sometimes when the optimizer thinks that something is very likely and going to return a vast set of data with little effort (i.e. almost all records are going to get returned), it chooses mostly loop joins because it only needs to get the first one and a loop join is good for only getting a couple records. When that turns out to not be true, it takes forever and a day to get results.
In your case, it sounds like it's very rare, so this choice hurts badly. Try instead doing something like
SELECT @count = COUNT(*) FROM ...
and then checking if that count is non-zero.