我一直在尝试对此进行测试,但我对我的测试有疑问,因为时间差异很大。
-- Scenario 1
SELECT * FROM Foo f
INNER JOIN Bar b ON f.id = b.id
WHERE b.flag = true;
-- Scenario 2
SELECT * FROM Foo f
INNER JOIN Bar b ON b.flag = true AND f.id = b.id;
从逻辑上讲,方案 2 似乎会更有效,但我不确定 SQL Server 是否足够智能来优化此方案。
最佳答案
不知道为什么你认为场景 2 “逻辑上”是 more efficient
。在INNER JOIN
上一切基本上都是一个过滤器,因此 SQL Server 可以将逻辑折叠到完全相同的底层计划形状。以下是来自 AdventureWorks2012 ( click to enlarge ) 的示例:
我更喜欢将连接条件与过滤条件分开,因此始终以左侧的格式编写查询。然而@HLGEM提出了一个很好的观点,这些子句在这种情况下可以互换,只是因为它是 INNER JOIN
。对于 OUTER JOIN
,将过滤器放置在联接条件中的外表上非常重要,否则您会无意中得到 INNER JOIN
并极大地改变查询的语义。因此,我关于如何折叠计划的建议仅适用于内部联接。
如果您担心性能,我会首先删除 SELECT *
并且只提取您实际需要的列(并确保有覆盖索引)。
四个月后,出现了另一个答案,声称性能通常会有差异,并将过滤条件放在ON
中条款会更好。虽然我不会否认这种情况确实有可能发生,但我认为这肯定不是常态,也不应该成为您始终将所有过滤条件放在 ON
中的借口。条款。
关于sql-server - 将约束移至连接是否比连接和 where 子句更有效?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15774878/