什么时候限制SQL Server 2005中的连接是有利的?

Joh*_*ohn 2 sql sql-server join constraints query-optimization

例如,假设您有这样的查询:

SELECT *
FROM table1 t1
JOIN table2 t2 ON t1.field1 = t2.field1 AND t1.year = t2.year
JOIN table3 t3 ON t1.field1 = t3.field1 AND t1.year = t3.year
JOIN table4 t4 ON t3.field2 = t4.field2 AND t3.year = t4.year
WHERE t1.year = '2010'
Run Code Online (Sandbox Code Playgroud)

这样做更快:

SELECT *
FROM table1 t1
JOIN table2 t2 ON t1.field1 = t2.field1 AND t1.year = t2.year AND t2.year = '2010'
JOIN table3 t3 ON t1.field1 = t3.field1 AND t1.year = t3.year AND t3.year = '2010'
JOIN table4 t4 ON t3.field2 = t4.field2 AND t3.year = t4.year AND t4.year = '2010'
WHERE t1.year = '2010'
Run Code Online (Sandbox Code Playgroud)

并不总是显而易见的是"更快".有时,SQL Server 2005中的执行计划表示一个比另一个更快,具体取决于索引.有时它会进行所有哈希匹配,这似乎是CPU密集型,而不是排序,然后是合并连接,似乎更加IO密集.根据执行计划的结果,现实世界的结果并不总是反映出人们的期望.


有人能为我澄清一些比另一种更好的简单场景吗?或者至少验证我的理解是否正确?在我看来,如果你加入索引良好的列,不使用一年或其他一些数据约束连接更有效,因为它可以使用基于索引的哈希匹配,并且不需要排序并使用临时表.

但是,如果要在两个查询中选择并加入非索引列,则添加时间约束会导致更少的行进行处理,并导致更快的排序和合并连接,即使它会产生一些(更多?)IO成本.


另外,令我困扰的是,table2中的pre-join选择没有考虑table1上where子句产生的有限值的子集,它似乎在不使用连接约束时选择table2中的所有行.由于table1中的行将受到限制b WHERE t1.year ='2010'且连接受限于t1.year = t2.year,不应该遵循连接只需要查看table2 where year =' 2010' ?

我想知道为什么它不首先查看where子句,并且在它甚至连接之前只选择匹配的行,我确信这背后有一些很好的推理,但是根据执行计划,数字它逃脱了我在这种情况下,从table2查看的行确实会发生变化,具体取决于您是否已将t2.year ='2010'添加到连接中.

提前谢谢你,对不起这个长期问题感到抱歉.我想尽可能清楚.请原谅我的经验不足.

Mit*_*eat 5

"它更快吗?" 没有.

查询优化器将决定哪个是最严格的结果集过滤器(如果您的统计信息是最新的,通常会做得很好).