代码之家  ›  专栏  ›  技术社区  ›  Randy Minder

左内连接与左外连接-为什么外连接需要更长的时间?

  •  26
  • Randy Minder  · 技术社区  · 14 年前

    我们有下面的查询。使用左外部联接执行需要9秒。将左外部更改为左内部会将执行时间缩短到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'
    
    4 回复  |  直到 14 年前
        1
  •  35
  •   Remus Rusanu    14 年前

    返回相同行数的事实是事后事实,查询优化器不能预先知道接受的每一行在标记中都有匹配的行,对吗?

    如果连接两个表A和B,假设A有100万行,B有1行。如果你说一个左边的内部连接b,它意味着只有匹配的行 二者都 结果可以是a和b,因此查询计划可以先自由扫描b,然后使用索引在a中进行范围扫描,并可能返回10行。但是如果你说的是左外连接,那么 至少 必须返回a中的所有行,因此计划必须扫描a中的所有内容,而不管它在b中找到什么。通过使用外部联接,您将消除一个可能的优化。

    如果你这样做了 知道 接受中的每一行都将有一个匹配的标记,那么为什么不声明一个外键来强制执行这个标记呢?优化器将看到约束,如果它是可信的,那么它将在计划中加以考虑。

        2
  •  28
  •   KM.    14 年前

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

    SET SHOWPLAN_ALL ON

    2)运行缓慢的查询

    3)查询将不运行,但将返回执行计划。存储此输出

    4)运行快速版本的查询

    5)查询将不运行,但将返回执行计划。存储此输出

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

    7)如果您仍然不知道为什么速度较慢,请在您的问题中发布两个输出(编辑它),这里的某人可以从中获得帮助。

        3
  •  6
  •   NebuSoft    14 年前

    这是因为在返回结果之前,左外部联接比内部联接做的工作更多。

    内部联接查找on语句为真的所有记录(因此,当它创建新表时,只放入与m.subid=a.subid匹配的记录)。然后,它将这些结果与WHERE语句(您上次修改的时间)进行比较。

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

    在结尾处得到相同数量结果的原因可能是巧合,因为在复制所有记录之后会出现WHERE子句。

    Join (SQL) Wikipedia

        4
  •  2
  •   MJB    14 年前

    等等——你的意思是“相同的行数……正在被 处理 “或那个”相同的行数 返回 “?通常,外部联接将处理更多的行,包括那些不匹配的行,即使它返回相同数量的记录。