【问题标题】:SQLServer join orderSQL Server 连接顺序
【发布时间】:2021-12-10 00:07:02
【问题描述】:

来自 SQLServer SELECT docs

以下步骤显示了 SELECT 语句的逻辑处理顺序或绑定顺序。此顺序确定一个步骤中定义的对象何时可用于后续步骤中的子句。例如,如果查询处理器可以绑定(访问)在 FROM 子句中定义的表或视图,则这些对象及其列可用于所有后续步骤。

  1. 来自
  2. 开启
  3. 加入

我的问题是执行计划中ONJOIN有什么区别?例如,如果查询是这样的:

SELECT *
FROM person JOIN county ON person.nationality=country.code

我知道第一步是检查FROM 表的权限:

  • 用户是否有权访问表personcountry

但是,例如,如果执行嵌套循环连接来连接两个表,ONJOIN 之间有什么区别?基于这种差异,为什么ON 需要JOIN 之前出现?

我想我唯一能想到的是它会首先检查ON 子句以确保连接有意义。两个例子可能是:

SELECT *
FROM person JOIN county ON 1=0 -- never need to do the join

还有:

SELECT *
FROM person JOIN county ON person.badcolumn = country.code

【问题讨论】:

    标签: sql sql-server sql-execution-plan


    【解决方案1】:

    我认为您误解了本文档的内容:

    我知道第一步是检查 FROM 表的权限

    这不是它所说的,它不是指用户权限。它指的是查询的每个部分如何在逻辑上引用查询的先前部分,但不能引用后面的部分,并解释了为什么SELECT 不能被引用,即使它是在查询的前面编写的。这是如何构建查询的编译时限制,而不是运行时限制。

    在这样的查询中:

    SELECT *
    FROM person p
    JOIN county c ON p.nationality = c.code
    
    • 首先计算FROM,并且不能引用查询的任何其他部分。
      例如,您不能这样做
    SELECT *
    FROM OPENJSON(p.JsonColumn)
    CROSS JOIN person p
    

    它必须是相反的顺序

    SELECT *
    FROM person p
    CROSS APPLY OPENJSON(p.JsonColumn)
    
    • 接下来是ON 子句,在JOIN 之前,正如您所说,这不清楚有什么区别。我相信这只是指一个嵌套的连接子句,如下所示
    SELECT *
    FROM person p
    JOIN county c
        JOIN state s ON c.state_id = s.state_id
      ON p.nationality = c.code
    

    这可能是微软的一个小误解,因为在这种情况下,嵌套连接不能引用查询的任何部分,即使是FROM

    • JOINs 和APPLYs 紧随其后,每个都可以按照严格的文本顺序引用前一个。

    例如,如果执行嵌套循环连接以连接两个表

    编译器完成的连接类型与这个问题无关。

    它将首先检查 ON 子句以确保连接有意义

    不,这纯粹是运行时语义。您可以在可以产生的任何条件下加入,即使在运行时已知它不会产生任何行。编译器可能会对其进行优化,但这是允许的。

    【讨论】:

      猜你喜欢
      • 2016-11-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-01-18
      • 1970-01-01
      • 2010-11-23
      • 1970-01-01
      相关资源
      最近更新 更多