SQL 查詢語句的執行順序解析

GuanJie發表於2019-12-03

代理搭建 - shadowsocks

https://www.jetbrains.com/shop/eform/opens...
https://blog.csdn.net/lianghecai52171314/a...
億圖

中文手冊

一、sql 解析順序為

UNION 是在 DISTINCTORDER BY 之間執行的,即:

  • ... -> DISTINCT -> UNION -> ORDER BY -> ...

SQL 查詢語句的執行順序解析

注意:由於 MYSQL 對查詢做了加強,所以在 GROUP BY 及之後的語句中允許使用 SELECT 中定義的 AS 別名 欄位。例如:SELECT SUM(num), WEEK(dt) AS wk FROM tmp_table WHERE 1 GROUP BY wk;

請謹記:這在其他資料庫中是不被允許的

(9) SELECT 
(10) DISTICNCT column,
(6) AGG_FUNC(column or expiression), ...
(1) FROM left_table
    (3) JOIN right_table
    (2) ON tablename.column = 
        other_tablename.column
(4) WHERE constraint_expiression
(5) GROUP BY column
(7) WITH CUBE|ROLLUP
(8) HAVING constraint_expiression
(11)ORDER BY column ASC|DESC
(12)LIMIT count OFFSET count;

從這個順序中我們可以發現,所有的查詢語句都是從 FROM 開始執行的。在實際執行過程中,每個步驟都會為下一個步驟生成一個虛擬表,這個虛擬表將作為下一個執行步驟的輸入。 接下來,我們詳細的介紹下每個步驟的具體執行過程。

1 FROM 執行笛卡爾積

FROM 才是 SQL 語句執行的第一步,並非 SELECT 。對FROM子句中的前兩個表執行笛卡爾積(交叉聯接),生成虛擬表VT1,獲取不同資料來源的資料集。

FROM子句執行順序為從後往前、從右到左,FROM 子句中寫在最後的表(基礎表 driving table)將被最先處理,即最後的表為驅動表,當FROM 子句中包含多個表的情況下,我們需要選擇資料最少的表作為基礎表。


2 ON 應用ON過濾器

對虛擬表VT1 應用ON篩選器,ON 中的邏輯表示式將應用到虛擬表 VT1中的各個行,篩選出滿足ON 邏輯表示式的行,生成虛擬表 VT2 。


3 JOIN 新增外部行

如果指定了OUTER JOIN保留表中未找到匹配的行將作為外部行新增到虛擬表 VT2,生成虛擬表 VT3。保留表如下:

  • LEFT OUTER JOIN把左表記為保留表
  • RIGHT OUTER JOIN把右表記為保留表
  • FULL OUTER JOIN把左右表都作為保留表

在虛擬表 VT2表的基礎上新增保留表中被過濾條件過濾掉的資料,非保留表中的資料被賦予NULL值,最後生成虛擬表 VT3

如果FROM子句包含兩個以上的表,則對上一個聯接生成的結果表和下一個表重複執行步驟1~3,直到處理完所有的表為止。


4 WHERE 應用WEHRE過濾器

對虛擬表 VT3應用WHERE篩選器。根據指定的條件對資料進行篩選,並把滿足的資料插入虛擬表 VT4

  • 由於資料還沒有分組,因此現在還不能在WHERE過濾器中使用聚合函式對分組統計的過濾。

  • 同時,由於還沒有進行列的選取操作,因此在SELECT中使用列的別名也是不被允許的。


5 GROUP BY 分組

按GROUP BY子句中的列/列表將虛擬表 VT4中的行唯一的值組合成為一組,生成虛擬表VT5。如果應用了GROUP BY,那麼後面的所有步驟都只能得到的虛擬表VT5的列或者是聚合函式(count、sum、avg等)。原因在於最終的結果集中只為每個組包含一行。

同時,從這一步開始,後面的語句中都可以使用SELECT中的別名。


AGG_FUNC 計算聚合函式

計算 max 等聚合函式。SQL Aggregate 函式計算從列中取得的值,返回一個單一的值。常用的 Aggregate 函式包涵以下幾種:

  • AVG:返回平均值

  • COUNT:返回行數

  • FIRST:返回第一個記錄的值

  • LAST:返回最後一個記錄的值

  • MAX: 返回最大值

  • MIN:返回最小值

  • SUM: 返回總和


7 WITH 應用ROLLUP或CUBE

對虛擬表 VT5應用ROLLUP或CUBE選項,生成虛擬表 VT6

CUBE 和 ROLLUP 區別如下:

  • CUBE 生成的結果資料集顯示了所選列中值的所有組合的聚合。

  • ROLLUP 生成的結果資料集顯示了所選列中值的某一層次結構的聚合。


8 HAVING 應用HAVING過濾器

對虛擬表VT6應用HAVING篩選器。根據指定的條件對資料進行篩選,並把滿足的資料插入虛擬表VT7。

HAVING 語句在SQL中的主要作用與WHERE語句作用是相同的,但是HAVING是過濾聚合值,在 SQL 中增加 HAVING 子句原因就是,WHERE 關鍵字無法與聚合函式一起使用,HAVING子句主要和GROUP BY子句配合使用。


9 SELECT 選出指定列

將虛擬表 VT7中的在SELECT中出現的列篩選出來,並對欄位進行處理,計算SELECT子句中的表示式,產生虛擬表 VT8


10 DISTINCT 行去重

將重複的行從虛擬表 VT8中移除,產生虛擬表 VT9。DISTINCT用來刪除重複行,只保留唯一的。


11 ORDER BY 排列

將虛擬表 VT9中的行按ORDER BY 子句中的列/列表排序,生成遊標 VC10 ,注意不是虛擬表。因此使用 ORDER BY 子句查詢不能應用於表示式。同時,ORDER BY子句的執行順序為從左到右排序,是非常消耗資源的。


12 LIMIT/OFFSET 指定返回行

從VC10的開始處選擇指定數量行,生成虛擬表 VT11,並返回撥用者。

老哥以後是要做 CTO 的人,這些技術怎麼能不會呢?

相關文章