LEFT INNER JOIN与LEFT OUTER JOIN - 为什么OUTER需要更长的时间?

Ran*_*der 26 sql sql-server

我们在下面有查询.使用LEFT OUTER连接需要9秒才能执行.将LEFT OUTER更改为LEFT INNER会将执行时间减少到2秒,并返回相同的行数.由于正在处理dbo.Accepts表中相同的行数,因此无论连接类型如何,为什么外部需要更长的时间?

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'
Run Code Online (Sandbox Code Playgroud)

Rem*_*anu 35

返回相同行数的事实是事后,查询优化器事先无法知道Accepts中的每一行在Marker中都有匹配的行,可以吗?

如果连接两个表A和B,则说A有100万行,B有1行.如果你说左内JOIN B则意味着只匹配的行 A和B可能会导致,所以查询计划是免费的B扫描,然后再使用索引做范围扫描在A,也许回到10行.但是如果你说A LEFT OUTER JOIN B然后至少必须返回A中的所有行,那么计划必须扫描A中的所有内容,无论它在B中找到什么.通过使用OUTER连接,您将消除一种可能的优化.

如果您确实知道 Accepts中的每一行都会在Marker中匹配,那么为什么不声明外键来强制执行此操作呢?优化器将看到约束,如果受信任,将在计划中考虑它.

  • 等等......没有"LENER INNER JOIN"这样的东西.它是"LEFT JOIN"或"LEFT OUTER JOIN"."INNER"已经意味着它是交叉点,交叉点只能是一个东西.这就是"OUTER"关键字的原因.不知道这个回复怎么得到了19票...除非我在这里错过了一些全新的东西. (13认同)
  • @NicholasPufal:由于SQL语法,你是正确的,[`INNER`没有一个`LEFT`也不是`RIGHT`(http://msdn.microsoft.com/en-us/library/ms177634.aspx).`LEFT`或`LEFT OUTER`意思相同,`OUTER`是一个可选的标记.关于此问题,OP已有很多评论.但我完全理解兰迪的意思,我猜他明白我的意思. (2认同)

KM.*_*KM. 28

1)在SQL Server Management Studio的查询窗口中,运行以下命令:

SET SHOWPLAN_ALL ON

2)运行慢速查询

3)您的查询将无法运行,但将返回执行计划.存储此输出

4)运行您的快速查询版本

5)您的查询将无法运行,但将返回执行计划.存储此输出

6)将慢查询版本输出与快速查询版本输出进行比较.

7)如果你仍然不知道为什么一个慢,请在你的问题中发布两个输出(编辑它),这里有人可以从那里帮助.

  • 我认为这更像是"教人钓鱼......"的答案.赞成该命令,我将强迫我的所有开发人员学习. (2认同)

Neb*_*oft 6

这是因为在发送结果之前,LEFT OUTER Join比INNER Join做更多的工作.

Inner Join查找ON语句为true的所有记录(因此,当它创建新表时,它只会放入与m.SubID = a.SubID匹配的记录).然后它将这些结果与您的WHERE语句(您上次修改时间)进行比较.

左外连接...获取第一个表中的所有记录.如果ON语句不为真(m.SubID不等于a.SubID),它只是NULLS该记录集的第二个表的列中的值.

您在结束时得到相同数量的结果的原因可能是巧合,因为WHERE子句在所有复制记录之后发生.

加入(SQL)维基百科