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.

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

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

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

我明白第一步是检查 FROM table(s):

的权限

但是,如果例如通过嵌套循环连接来连接两个 table,那么 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

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

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

  • 接下来是 JOINAPPLY,每个都可以按照严格的文本顺序引用前一个。

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

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