当前位置: 首页 > 面试题库 >

ANSI JOIN与非ANSI JOIN查询的执行方式会有所不同吗?

公冶渝
2023-03-14
问题内容

我在大约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

如果我将这样的查询替换为以下内容,是否可以提高性能:

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

还是一样?


问题答案:

这两个查询是相同的,除了第二个查询是ANSI-92
SQL语法,而第一个查询是未合并join子句的较旧的SQL语法。尽管您可能想检查一下,但它们应该产生完全相同的内部查询计划。

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

  • JOIN子句的使用将关系逻辑与过滤器逻辑(WHERE)分开,因此更简洁,更易于理解。
  • 该特定查询无关紧要,但是在某些情况下,较旧的外部联接语法(使用+)含糊不清,因此查询结果依赖于实现,或者根本无法解析该查询。这些在ANSI-92中不会发生
  • 这是一个好习惯,因为当今大多数开发人员和dba都将使用ANSI-92,因此您应该遵循该标准。当然,所有现代查询工具都会生成ANSI-92。
  • 正如@gbn指出的那样,它的确可以避免意外的交叉连接。

我本人抵制ANSI-92一段时间,因为旧语法在概念上略有优势,因为将SQL想象成所有使用的表的大量笛卡尔联接,然后进行过滤操作会更容易-
这是一种有用的思维方法掌握SQL查询的功能。但是,几年前,我决定需要与时俱进,经过一段较​​短的调整后,我现在非常喜欢它-
主要是因为上面提到的第一个原因。唯一应该脱离ANSI-92语法或者不使用该选项的地方是自然连接,这是隐式的危险。



 类似资料:
  • 问题内容: SQL2008。 我有一个测试表: 我用10k测试行填充它。 我运行以下两个查询: 我不知道为什么这两个查询有不同的执行计划。 查询1确实针对UQ_Sale_RowVersion索引进行索引搜索。 查询2对PK_Sale进行索引扫描。 我想查询2做索引查找。 我将不胜感激。 谢谢你。 [编辑] 尝试使用datetime2而不是rowversion。同样的问题。 我也尝试强制使用索引(查

  • 问题内容: 他们俩都做同一件事,只是做事不同吗? 除了使用之间还有什么区别 和 ? 问题答案: 运行标准SQL语句,并要求您正确转义所有数据,以避免SQL注入和其他问题。 运行一个准备好的语句,该语句使您可以绑定参数,以避免需要转义或引用参数。如果您多次重复查询,效果也会更好。准备语句的示例: 最佳实践是坚持准备好的语句并提高安全性。

  • 在程序中有一部分代码,用于执行查询: 数据集 () 表应该有大约 20000 条记录(行计数),但在程序内部,它在调试模式下说只有 20 条记录。 我在同一个数据库表上单独运行了脚本,该表在 SQL Server 连接字符串中使用,但在 SQL Server Management Studio 中,它按预期返回了 20000 条记录。 该脚本看起来像: 它是相同的脚本文本,代码也会执行该文本。 有

  • 我有稍微不同的选择查询从同一个表中读取数据。 和正在更改。 在Laravel中,我最终为每种类型使用了1个查询,但是有10种类型,这意味着10 db连接——这不好。 将这些查询合并到一个查询中,以便建立一个数据库连接以获取所有数据的好方法是什么? (我正在寻找Laravel查询生成器实现这一点的方法)

  • 问题内容: 我已经开发了一个用户批量上传模块。有两种情况,当数据库有零条记录时,我批量上传了20000条记录。大约需要5个小时。但是,当数据库已经有大约30 000条记录时,上传速度将非常缓慢。上载2万条记录大约需要11个小时。我只是通过fgetcsv方法读取CSV文件。 下面是运行的查询。(我正在使用Yii框架) 如果存在,请更新用户: 如果用户不存在,请插入新记录。 表引擎类型为MYISAM。