SQL服务器与存在的性能
-
20-09-2019 - |
题
我很好奇它的以下将更加有效?
我一直有点谨慎使用 IN
因为我相信SQL服务器变的结果集成一个大的 IF
发言。对于大量结果,这可能导致贫穷的性能。小结果套,我不确定既是可取的。对于大的结果集,就不会 EXISTS
更有效率吗?
WHERE EXISTS (SELECT * FROM Base WHERE bx.BoxID = Base.BoxID AND [Rank] = 2)
与
WHERE bx.BoxID IN (SELECT BoxID FROM Base WHERE [Rank = 2])
解决方案
EXISTS
将更快,因为一旦发动机已发现命中时,将退出期待作为条件已证明如此。
使用IN
,它会收集所有从子查询的结果进一步处理之前。
其他提示
接受的答案是短视并且该问题有点松:
1)既没有明确提到覆盖索引是否存在于 的左,右,或者两侧上。
2)既不考虑输入左侧集的大小和 输入右侧组。结果 (问题只是提到的整体大结果集)。
相信优化足够智能“在”之间转换与“存在”时,有由于(1)和(2),否则它可能只是被用来作为提示(例如存在于显著成本差异鼓励在右侧使用可搜索的索引)。
这两种形式可以转换为内部加入的形式,已连接顺序颠倒过来,并运行作为环,哈希或合并 - 基于在左预计行计数(左和右)和索引存在,右,或两者侧上。
我已经做了SQL Server 2005和2008上的一些测试,并同时在EXISTS和IN回来完全相同的实际执行计划,其他都表示。优化器是最佳的。 :)
一个需要注意的虽然存在,和JOIN如果你不短语查询恰到好处有时会返回不同的结果:的 http://weblogs.sqlteam.com/mladenp/archive/2007/05/18/60210.aspx
我会去与性存在IN,见下面的链接:
在执行计划通常将是相同的在这些情况下,但直到你看到在索引等的所有其他方面优化的因素,你真的永远不会知道。
因此,在不同的存在,也不会产生同样的执行计划。
通常存在是用于一个相关查询,这意味着你将参加所存在的内部查询与你的外部查询。这将增加更多的步骤产生的结果,如需要解决的外部查询联接和内部查询加入后的比赛他们在那里条款,以加入这两者。
通常是使用不相关的内部查询与外部查询,并且可以解决的唯一的一个步骤(在最好的情况下).
考虑这样的:
如果你用在内的查询结果是数以百万计的排不同的价值观,它可能会执行速度慢于存在,鉴于存在的查询是高性能的(有权索引,以加入与外查询)。
如果你使用了存在和参与你的外部查询复杂(需要更多的时间来执行,没有适当的索引),它将缓慢的查询由数目排在外部表,有时预计完成时间可以在天。如果行的数量是可以接受你给硬件,或者基数的数据是正确的(例如减少不同的数值,在一个大数据集)在可以执行的速度比存在。
所有上述会注意到,当你有一个相当数量的排在每个表格(通过公平我是说,超过你的CPU处理和/或ram阈值缓存).
所以答案是它依赖。你可以写一个复杂的查询内在或存在,但作为一项规则的拇指,你应该尝试使用在有限的一组不同的价值和存在的时候你有很多行有很多不同的价值观。
诀窍是数量限制的行为进行扫描。
问候,
MarianoC
要优化EXISTS
,是非常字面;有些事情必须是有,但你实际上并不需要任何数据从相关联的子查询返回。你只是评估布尔条件。
所以:
WHERE EXISTS (SELECT TOP 1 1 FROM Base WHERE bx.BoxID = Base.BoxID AND [Rank] = 2)
由于相关联的子查询是RBAR
,第一结果命中使得条件为真,并且它没有进一步处理。
有这里的许多误导答案的答案,包括高度upvoted一个(虽然我不相信他们的OPS意味着伤害)。的简短的回答是:这些是相同的强>
。有在(T-)SQL语言的关键字,但最终,真正发生在硬件的唯一事情就是操作所看到在执行查询计划。
我们做当我们调用[NOT] IN
和[NOT] EXISTS
是半加入(使用NOT
当反连接)的关系(理论数学)操作。这不是一个巧合,相应的SQL服务器的操作具有的同名的。没有任何的操作,提到IN
或EXISTS
任何地方 - 只有(反)半连接。因此,有没有办法,一个逻辑上等同IN
VS EXISTS
的选择可能会影响性能,因为有一个且只有这样,(反)半联接执行操作,以获得他们的结果
的示例:
查询1(计划)
select * from dt where dt.customer in (select c.code from customer c where c.active=0)
查询2(计划)
select * from dt where exists (select 1 from customer c where c.code=dt.customer and c.active=0)
关掉我的头顶,不能保证是正确的:我相信,第二次将以更快的速度在这种情况。
- 在第一、相关查询很可能会引起查询要运行每一行。
- 在第二例中,查询应该只运行一次,由于不相关的。
- 在第二个例子中,
IN
会短路,尽快为它找到匹配。