我们有下面的查询。使用LEFT OUTER联接需要9秒钟才能执行。将LEFT OUTER更改为LEFT INNER可以将执行时间减少到2秒,并且返回 相同 数量的行。由于正在处理dbo.Accepts表中相同数量的行,而不论联接类型如何,为什么外层要花3倍的时间?
SELECT CONVERT(varchar, a.ReadTime, 101) as ReadDate, a.SubID, a.PlantID, a.Unit as UnitID, a.SubAssembly, m.Lot FROM dbo.Accepts a WITH (NOLOCK) LEFT OUTER Join dbo.Marker m WITH (NOLOCK) ON m.SubID = a.SubID WHERE a.LastModifiedTime BETWEEN @LastModifiedTimeStart AND @LastModifiedTimeEnd AND a.SubAssembly = '400'
返回相同行数的事实是事后事实,查询优化器无法预先知道Accepts中的每一行在Marker中都有匹配的行,可以吗?
如果将两个表A和B连接在一起,则说A有100万行,而B有1行。如果你说左内JOIN B则意味着只匹配的行 既 A和B可能会导致,所以查询计划是免费的B扫描,然后再使用索引做范围扫描在A,也许回到10行。但是,如果您说A LEFT OUTER JOIN B,那么 至少 必须返回A中的所有行,因此该计划必须扫描A中的所有内容,无论它在B中发现什么。通过使用OUTER join,您将消除一种可能的优化方法。
如果您确实 知道“ 接受”中的每一行在“标记”中都会有一个匹配项,那么为什么不声明外键来强制执行此操作呢?优化器将看到约束,如果受约束,则会在计划中将其考虑在内。