从SQLServerSELECT
文档:
以下步骤显示SELECT语句的逻辑处理顺序或绑定顺序。此顺序确定一个步骤中定义的对象何时可用于后续步骤中的子句。例如,如果查询处理器可以绑定(访问)FROM子句中定义的表或视图,那么这些对象及其列将可用于所有后续步骤。
- FROM
- 在
- 联接
我的问题是执行计划中的ON
和JOIN
之间有什么区别?例如,如果查询类似于:
SELECT *
FROM person JOIN county ON person.nationality=country.code
我理解第一步是检查FROM
表的权限:
- 用户是否有权访问表
person
和country
但是,例如,如果执行嵌套循环联接来联接两个表,那么ON
和JOIN
之间有什么区别?基于这种差异,为什么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
JOIN
s和APPLY
s紧随其后,它们都可以严格按照文本顺序引用前一个
例如,如果执行嵌套循环联接来联接两个表
编译器执行的联接类型与此问题无关。
它将首先检查ON子句,以确保连接有意义
不,这纯粹是一个运行时语义。您可以在任何可以生成的条件下进行联接,即使在运行时已知不生成任何行。编译器可能会对其进行优化,但这是允许的。