ANSI JOIN与非ANSI JOIN查询的执行方式是否不同?

aba*_*hev 59 sql t-sql sql-server join

我在~7000行T-SQL存储过程中有我的业务逻辑,其中大多数都有下一个JOIN语法:

SELECT A.A, B.B, C.C
FROM aaa AS A, bbb AS B, ccc AS C
WHERE
    A.B = B.ID
AND B.C = C.ID
AND C.ID = @param
Run Code Online (Sandbox Code Playgroud)

如果我用这个替换这样的查询,我会获得性能增长:

SELECT A.A, B.B, C.C
FROM aaa AS A
JOIN bbb AS B
   ON A.B = B.ID
JOIN ccc AS C
   ON B.C = C.ID
   AND C.ID = @param
Run Code Online (Sandbox Code Playgroud)

或者他们是一样的?

Cru*_*han 77

这两个查询是相同的,除了第二个是ANSI-92 SQL语法,第一个是没有包含join子句的旧SQL语法.虽然您可能想检查,但它们应该生成完全相同的内部查询计划.

出于多种原因,您应该使用ANSI-92语法

  • 使用JOIN子句将关系逻辑与过滤器逻辑(WHERE)分开,因此更清晰,更容易理解.
  • 这与特定查询无关,但在某些情况下,较旧的外连接语法(使用+)不明确且查询结果因此依赖于实现 - 或者查询根本无法解析.ANSI-92不会出现这些情况
  • 这是一个很好的做法,因为大多数开发人员和dba现在都会使用ANSI-92,你应该遵循标准.当然,所有现代查询工具都将生成ANSI-92.
  • 正如@gbn指出的那样,它确实倾向于避免偶然的交叉连接.

我自己抵制ANSI-92一段时间了,因为旧语法略有概念上的优势,因为它更容易设想SQL作为所有表的大规模笛卡尔连接,然后是过滤操作 - 一种有用的心理技术用于掌握SQL查询正在执行的操作.然而,几年前我决定我需要与时俱进,经过相对较短的调整期后,我现在非常喜欢它 - 主要是因为上面提到的第一个原因.唯一一个应该偏离ANSI-92语法的地方,或者更确切地说不使用该选项的地方,是自然连接,这是隐含的危险.

  • 10 年前,我也有类似的倾向,放弃了旧的逗号/等于连接形式,但没有回头。 (2认同)

one*_*hen 5

第二种结构在 SQL 社区中称为“中缀连接语法”。第一个构造 AFAIK 没有被广泛接受的名称,所以我们称之为“旧式”内部连接语法。

通常的论点是这样的:

“传统”语法的优点:谓词WHERE以任何顺序在子句中物理组合在一起,这使得查询一般,尤其是 n 元关系,更容易阅读和理解(ON中缀语法的子句可以将谓词展开所以你必须在视觉距离内寻找一个表格或一列的外观)。

“传统”语法的缺点:省略其中一个“连接”谓词时不会出现解析错误,结果是笛卡尔积(CROSS JOIN在中缀语法中称为 a ),这样的错误很难检测和调试。此外,“join”谓词和“filtering”谓词在WHERE子句中物理组合在一起,这可能导致它们相互混淆。