(正在使用SQL Server 2012)
我找到了一些有关查询优化的主题,并将EXISTS与COUNT进行了比较,但找不到这个确切的问题。
我有一个查询,看起来像这样:
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
该查询可立即运行(尽管数据库很大,大约70Gb)。
当我将查询包装在EXISTS中时,如下所示:
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
突然,查询大约需要5-6秒才能完成。我试过指定IF EXISTS(选择TOP 1 FROM …),还试过NOT EXISTS(速度甚至更慢),但是都没有加快速度。
如果正常的选择查询基本上立即完成,那么有人知道为什么将其包装在EXISTS中会导致大量额外的计算吗?和/或任何人都有解决此问题的想法(如果原始查询根本找不到任何记录,我只是想抛出一个错误)。
谢谢!
您是否尝试使用TOP 1运行原始查询?最有可能会同样慢。
有时,当优化器认为某件事很有可能并会毫不费力地返回大量数据(即几乎所有记录都将被返回)时,它大多选择循环连接,因为它只需要获取第一个和一个循环连接仅可用于获取一对记录。如果事实并非如此,那将需要一整天和一天的时间才能得到结果。
在您的情况下,这听起来非常罕见,因此这种选择会带来很大的伤害。请尝试做类似的事情SELECT @count = COUNT(*) FROM ...,然后检查该计数是否为非零。
SELECT @count = COUNT(*) FROM ...