【问题标题】:Execution precedence in SQL multi joinsSQL 多连接中的执行优先级
【发布时间】:2016-08-28 10:12:12
【问题描述】:

在执行具有多个连接的查询时,SQL 是否遵循任何优先级。

一个示例查询

SELECT emp.ename, emp.DEPTNO, emp.JOB, emp.SAL 
FROM EMPLOYEE emp 
INNER JOIN DEPARTMENT Dept On emp.DEPTNO = Dept.DEPTNO
INNER JOIN (
    SELECT MAX(emp.sal) maxSal, emp.DEPTNO 
    FROM EMPLOYEE emp 
    GROUP BY emp.DEPTNO
    ) AS maxSalData
 ON emp.DEPTNO = maxSalData.DEPTNO AND emp.SAL = maxSalData.maxSal

我的问题是想知道当存在多个连接时如何执行 SQL 查询。

【问题讨论】:

  • 无论JOIN如何,优化器都会将行数最少的表放在最前面,以尽量减少访问的数据
  • @Mihai,具体产品。不要忘记索引等。
  • 您问的是 SQL Server 还是 Oracle?不要标记未涉及的产品。
  • @jarlh 当然,还有统计问题等等。只是对一般问题的一般评论。
  • SQL 是一个基于集合的表达式,它被“编译”到其他代码中执行。此“编译”代码在 SQL Server 中称为“执行计划”,在 Oracle 中称为“解释计划”。 “编译”考虑了当前的统计数据(可能是最新的,也可能不是最新的)、索引、您的查询、参数和一大堆其他因素。它所做的确切细节很复杂,并且在 RDBMS 甚至版本之间有所不同。但简短的回答是;大多数优化者估计不同选项的成本,并找出估计成本最低的选项。包括重新排序您的连接。

标签: sql sql-server database oracle join


【解决方案1】:

优化器确定连接的顺序。

我想指出,有一种更简单的查询方式:

SELECT emp.ename, emp.DEPTNO, emp.JOB, emp.SAL 
FROM (SELECT emp.*, MAX(emp.sal) OVER (PARTITION BY emp.DEPTNO) as maxsal
      FROM EMPLOYEE emp
     ) emp;

所以:

  • JOINDEPARTMENT 不是必需的。
  • 子查询不是必须的,可以用窗口/解析函数代替

因此,关于连接处理顺序的问题是错误的,因为更好的查询版本甚至没有明确的JOINs。但是,答案是优化器决定了JOINs 的执行顺序。 SQL 作为一种语言的意图是它是声明性,而不是过程。也就是说,它描述了要产生的结果,但没有说明如何完成。

【讨论】:

  • 加入 DEPARTMENT 将负责消除部门编号无效的 EMPLOYEE 记录。在一些公司(不要问我在哪里!:-) 某些员工(不要问我是谁!:-) 被分配到不存在的部门各种原因。 (不要问我为什么!:-)
  • declarative;一定记得在我的解释中使用它。
  • 戈登,感谢您的回复。我给出的 sql 只是一个例子。可能有很多真实场景​​会更多地使用连接。
猜你喜欢
  • 1970-01-01
  • 2011-04-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-11
  • 2017-07-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多