SQLServer连接顺序
SQLServer join order
来自 SQLServer SELECT
docs:
The following steps show the logical processing order, or binding order, for a SELECT statement. This order determines when the objects defined in one step are made available to the clauses in subsequent steps. For example, if the query processor can bind to (access) the tables or views defined in the FROM clause, these objects and their columns are made available to all subsequent steps.
- 来自
- 开启
- 加入
我的问题是执行计划中的ON
和JOIN
有什么区别?例如,如果查询类似于:
SELECT *
FROM person JOIN county ON person.nationality=country.code
我明白第一步是检查 FROM
table(s):
的权限
- 用户是否有权访问 tables
person
和 country
?
但是,如果例如通过嵌套循环连接来连接两个 table,那么 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
我认为您误解了本文档的内容:
I would understand that the first step would be to check privileges for the FROM table(s)
这不是它在说什么,它不是指用户权限。它指的是查询的每个部分如何在逻辑上引用查询的前面部分,但不能引用后面的部分,并解释了为什么 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
这可能是 Microsoft 的一个轻微误解,因为在这种情况下,嵌套连接不能引用查询的 any 部分,即使是 FROM
- 接下来是
JOIN
和 APPLY
,每个都可以按照严格的文本顺序引用前一个。
if for example a nested loop join is done to join the two tables
编译器完成的连接类型与此问题无关。
it will first check the ON clause to make sure the join makes sense
不,那纯粹是运行时语义。您可以根据可以产生的任何条件加入,即使在运行时已知不会产生任何行。编译器可能会优化掉它,但这是允许的。
来自 SQLServer SELECT
docs:
The following steps show the logical processing order, or binding order, for a SELECT statement. This order determines when the objects defined in one step are made available to the clauses in subsequent steps. For example, if the query processor can bind to (access) the tables or views defined in the FROM clause, these objects and their columns are made available to all subsequent steps.
- 来自
- 开启
- 加入
我的问题是执行计划中的ON
和JOIN
有什么区别?例如,如果查询类似于:
SELECT *
FROM person JOIN county ON person.nationality=country.code
我明白第一步是检查 FROM
table(s):
- 用户是否有权访问 tables
person
和country
?
但是,如果例如通过嵌套循环连接来连接两个 table,那么 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
我认为您误解了本文档的内容:
I would understand that the first step would be to check privileges for the FROM table(s)
这不是它在说什么,它不是指用户权限。它指的是查询的每个部分如何在逻辑上引用查询的前面部分,但不能引用后面的部分,并解释了为什么 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
这可能是 Microsoft 的一个轻微误解,因为在这种情况下,嵌套连接不能引用查询的 any 部分,即使是 FROM
- 接下来是
JOIN
和APPLY
,每个都可以按照严格的文本顺序引用前一个。
if for example a nested loop join is done to join the two tables
编译器完成的连接类型与此问题无关。
it will first check the ON clause to make sure the join makes sense
不,那纯粹是运行时语义。您可以根据可以产生的任何条件加入,即使在运行时已知不会产生任何行。编译器可能会优化掉它,但这是允许的。