【发布时间】:2015-09-10 23:56:48
【问题描述】:
(正在使用 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
这个查询在瞬间运行(虽然 db 很大,大约 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 (SELECT TOP 1 FROM... 并且还尝试了 NOT EXISTS (甚至更慢)。但都无法加快速度。
如果正常的选择查询基本上立即完成,那么有谁知道为什么将它包装在 EXISTS 中会导致这么多额外的计算?和/或任何人有任何解决此问题的想法(如果原始查询完全找到任何记录,我只是试图抛出错误)。
谢谢!
【问题讨论】:
-
在
EXISTS中包裹的查询是否完全相同?选择前 1 不会做任何事情,因为存在扫描表,如果找到记录,则返回 true 并且不打扰其他计算 afaik。但首先我想我会从执行计划开始。 -
是的,查询完全相同。已编辑原始问题以使其更清楚。不确定执行计划是什么意思?
-
可能是普通查询被缓存,而不是每次都实际查询数据,而不是exist()
-
执行计划显示在查询执行期间究竟做了什么。您可以在链接中启用它,然后在此处截屏并上传两个计划,这样我们就可以看到发生了什么。 i.imgur.com/oiLRdLb.png
-
@user1221684 - SQL Server 不缓存实际查询结果。刚刚编译了计划缓存中的执行计划和缓冲池中的底层数据/索引页。
标签: sql sql-server sql-server-2012 query-optimization exists