SQLServer加入顺序



从SQLServerSELECT文档:

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

  1. FROM
  2. 联接

我的问题是执行计划中的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

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

我知道第一步是检查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子句,以确保连接有意义

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

相关内容

  • 没有找到相关文章

最新更新