簡體   English   中英

相關子查詢的SQL執行順序

[英]SQL order of execution for correlated subquery

我有以下人員表

+---------+----------+-------------+
| name    | dept_nbr | job_title   |
+---------+----------+-------------+
| Michael | 14       | Programmer  |
| Kumar   | 14       | Programmer  |
| Dave    | 14       | Programmer  |
| Jane    | 14       | Manager     |
| Carol   | 37       | Programmer  |
| Joe     | 37       | Programmer  |
| John    | 59       | CEO         |
+---------+----------+-------------+

問題 :查找程序員少於3個的所有dept_nbr(部門)。

工作查詢:

SELECT DISTINCT dept_nbr
  FROM Personnel AS P1
 WHERE (SELECT COUNT(P2.dept_nbr)
          FROM Personnel AS P2
         WHERE P1.dept_nbr = P2.dept_nbr AND P2.job_title = 'Programmer') < 3;

結果:

37
59

筆記:

部門14被正確地包括在內,因為它有3個程序員(3個等於但不少於3個)。 部門59沒有程序員,也正確地包含在結果中。

我的問題:

執行上述查詢時,通用SQL引擎如何繼續? 根據我的閱讀,SQL執行順序是(粗略地):From,Where,Group By,Having和Select。 那么,以下是正確的嗎?

1 -外部查詢將Personnel表的每一行作為P1傳遞到Inner查詢中。

2.a -內部查詢將整個Personnel表掃描為P2,逐行查找滿足條件“P1.dept_nbr = P2.dept_nbr AND P2.job_title ='Programmer'”的行。

2.b -一旦內部查詢完成整個表,它就會對匹配的dept_nbr值進行COUNT並將其返回給外部查詢。

3 -在外部查詢中,如果從內部查詢返回的計數滿足條件“WHERE(內部查詢計數結果)<3”,則P1行的對應dept_nbr被選中。

4 -在外部查詢處理的所有行之后,外部查詢對結果執行DISTINCT並顯示唯一的dept_nbr值。

我的理解是否正確? 具體來說,外部查詢是否在最后執行DISTINCT(步驟#4)? 看來,通過這種方式,內部查詢會執行冗余掃描(例如,它會在第一次傳遞中確實得到答案時四次處理dept_nbr = 14)。

我在sqlfiddle.com上用MySQL 5.6測試了上面的查詢。

執行上述查詢時,通用SQL引擎如何繼續? 根據我的閱讀,SQL執行順序是(粗略地):From,Where,Group By,Having和Select。

這句話 - 通常 - 不正確。 SQL按您描述的順序進行解析 但是, 執行由優化程序確定,可能與原始查詢幾乎沒有關系。 請記住:SQL是一種描述性語言,而不是過程語言。 它描述了結果集,而不是計算結果集的具體步驟。

也就是說,MySQL的執行計划比大多數其他數據庫(特別是具有更好優化器的更高級數據庫)更接近查詢。 並且,幾乎所有數據庫都將按照您為此查詢描述的步驟繼續進行。 子查詢中的聚合限制了優化的選擇。

如果要消除冗余,請在過濾之前執行select distinct

SELECT dept_nbr
FROM (SELECT DISTINCT dept_nbr FROM Personnel P1) P1
WHERE (SELECT COUNT(P2.dept_nbr)
       FROM Personnel AS P2
       WHERE P1.dept_nbr = P2.dept_nbr AND P2.job_title = 'Programmer'
      ) < 3;

您還可以通過聚合更簡單地執行此操作:

select dept_nbr
from personnel
group by dept_nbr
having sum(job_title = 'Programmer') < 3;

在查詢之前添加EXPLAIN (或EXPLAIN EXTENDED ),它應該為您提供解釋計划,該計划將詳細說明查詢順序的步驟。 在嘗試優化查詢時,這是一個非常有用的工具。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM