最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

SQL查詢執(zhí)行順序分析

 更新時間:2023年09月13日 11:01:55   作者:emanjusaka  
這篇文章主要為大家介紹了SQL查詢執(zhí)行順序分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

前言

了解 SQL 查詢的執(zhí)行順序?qū)ξ覀兘鉀Q一些問題很有幫助,有時我們可能會疑惑為什么不能對分組的結(jié)果進(jìn)行篩選這樣類似的問題?之前一直不是理解這個問題,在了解了SQL 查詢的執(zhí)行順序之后這個問題也就迎刃而解。在我們對 SQL 查詢語句進(jìn)行分析優(yōu)化時,掌握執(zhí)行順序也是有一定幫助的。

一、理論順序

上面是圖示 SQL 的執(zhí)行順序,下面用列表列出:

  • FROM

  • ON

  • JOIN

  • WHERE

  • GROUP BY

  • CUBE | ROLLUP

  • HAVING

  • SELECT

  • DISTINCT

  • ORDER BY

  • LIMIT

上面所列出的執(zhí)行順序能幫助我們解答一些問題:

  • 為啥不能對窗口函數(shù)的執(zhí)行結(jié)果進(jìn)行過濾?

    因為窗口函數(shù)在 SELECT 步驟執(zhí)行,而這步是在 WHERE 和 GROUP BY 之后

  • 可以對分組的結(jié)果進(jìn)行篩選嗎?

    不可以,因為 GROUP BY 在 WHERE 之后執(zhí)行

  • 可以對分組后的結(jié)果進(jìn)行排序嗎?

    可以,因為 ORDER BY 在 GROUP BY 之后。

二、代碼示例

學(xué)生表

成績

查詢語句

查詢來自天津且總成績高于70分,并且查詢他們的總成績,查詢結(jié)果按成績降序排列

SELECT
	ss.student_id,sum(se.grade) as total,ss.city
FROM
	students ss
	LEFT JOIN score se ON ss.student_id = se.student_id 
WHERE
	ss.city = "天津"
GROUP BY ss.student_id
HAVING sum(se.grade) > 70
ORDER BY total DESC
LIMIT 10

查詢結(jié)果

三、分析 SQL 執(zhí)行過程

SQL 運(yùn)行的每個操作都會產(chǎn)生一張?zhí)摂M表,只不過這些虛擬表對用戶是透明的,只有最后一步生成的虛擬表才會返回給用戶。

  • 第一步執(zhí)行的是對 FROM 字句前后的兩張表 students 和 score 進(jìn)行笛卡爾積操作,生成虛擬表VT1。

  • 應(yīng)用 ON 過濾器

    在虛擬表 VT1 中執(zhí)行過濾操作,過濾條件為:ss.student_id = se.student_id ?

    對于在 ON 過濾條件下的 NULL 值比較,此時的比較結(jié)果為 UNKNOWN,卻被視為 FALSE 來進(jìn)行處理,即兩個 NULL 并不相同。但是在下面兩種情況下認(rèn)為兩個 NULL 值的比較是相等的:

    • GROUP BY 子句把所有 NULL 值分到同一組

    • ORDER BY 子句中把所有 NULL 值排列在一起

    在產(chǎn)生虛擬表 VT2 時,會增加一個額外的列來表示 ON 過濾條件的返回值,返回值有 TRUE、FALSE、UNKNOWN。取出比較值為 TRUE 的記錄,產(chǎn)生虛擬表 VT2。

  • 添加外部行

    這一步只有在連接類型為 OUTER JOIN 時才發(fā)生,如 LEFT OUTER JOIN、RIGHT OUTERJOIN、FULL OUTER JOIN。雖然在大多數(shù)時候我們可以省略 OUTER 關(guān)鍵字,但 OUTER 代表的就是外部行。LEFT OUTER JOIN 把左表記為保留表,RIGHT OUTER JOIN 把右表記為保留表,F(xiàn)ULL OUTER JOIN 把左右表都記為保留表。添加外部行的工作就是在 VT2 表的基礎(chǔ)上添加保留表中被過濾條件過濾掉的數(shù)據(jù),非保留表中的數(shù)據(jù)被賦予 NULL 值,最后生成虛擬表 VT3

  • 應(yīng)用 WHERE 過濾器

    對上一步驟產(chǎn)生的虛擬表 VT3 進(jìn)行 WHERE 條件過濾,只有符合<where_condition>的記錄才會輸出到虛擬表 VT4 中

    在當(dāng)前應(yīng)用 WHERE 過濾器時,有兩種過濾是不被允許的:

    • 由于數(shù)據(jù)還沒有分組,因此現(xiàn)在還不能在 WHERE 過濾器中使用 where_condition=MIN(col)這類對統(tǒng)計的過濾

    • 由于沒有進(jìn)行列的選取操作,因此在 SELECT 中使用列的別名也是不被允許的,如 SELECT city as c from students WHERE c = '天津' 是不允許出現(xiàn)的

  • 分組

    在本步驟中根據(jù)指定的列對上個步驟中產(chǎn)生的虛擬表進(jìn)行分組,最后得到虛擬表 VT5

  • 應(yīng)用 HAVING 過濾器

    在該步驟中對于上一步產(chǎn)生的虛擬表應(yīng)用 HAVING 過濾器,HAVING 是對分組條件進(jìn)行過濾的篩選器。生成虛擬表VT6。

  • 處理 SELECT 列表

    在這一步中,將 SELECT 中指定的列從上一步產(chǎn)生的虛擬表中選出生成虛擬表 VT7。

  • 應(yīng)用 ORDER BY 字句

    根據(jù) ORDER BY 子句中指定的列對上一步輸出的虛擬表進(jìn)行排列,返回新的虛擬表 VT8。

    注意:在 MySQL 數(shù)據(jù)庫中,NULL 值在升序過程中總是首先被選出,即 NULL 值在 ORDER BY 子句中被視為最小值

  • LIMIT 子句

    在該步驟中應(yīng)用 LIMIT 子句,從上一步驟的虛擬表中選出從指定位置開始的指定行數(shù)據(jù)。對于沒有應(yīng)用 ORDER BY 的 LIMIT 子句,結(jié)果同樣可能是無序的,因此 LIMIT 子句通常和 ORDER BY 子句一起使用。

四、注意

上面所討論的順序皆為理論上的執(zhí)行順序,實際上數(shù)據(jù)庫引擎并不是通過連接、過濾和分組來運(yùn)行查詢,因為它實現(xiàn)了一系列優(yōu)化來提升查詢速度(不影響最終的返回結(jié)果)。數(shù)據(jù)庫引擎可能會為了提高查詢的速度把一些過濾條件進(jìn)行提前,當(dāng)然前提是不會對返回的結(jié)果造成影響。

SELECT
	ss.student_id,sum(se.grade) as total,ss.city
FROM
	students ss
	LEFT JOIN score se ON ss.student_id = se.student_id 
WHERE
	ss.city = "天津"

這個 sql 學(xué)生城市是天津的只有三個,如果在學(xué)生很多的情況下如果先做城市的篩選后再對兩張表做笛卡爾積可以很大程度的提升性能,并且也不會對返回的結(jié)果造成影響。這時實際上SQL的執(zhí)行順序可能就與理論上的執(zhí)行順序不一樣了。

參考資料 SQL queries don't start with SELECT

以上就是SQL查詢執(zhí)行順序分析的詳細(xì)內(nèi)容,更多關(guān)于SQL查詢執(zhí)行順序的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • MySQL線上死鎖分析實戰(zhàn)

    MySQL線上死鎖分析實戰(zhàn)

    這篇文章主要介紹了MySQL線上死鎖分析實戰(zhàn),文章內(nèi)容分析的很清楚,有對于這方面不懂的同學(xué)可以研究下
    2021-02-02
  • MySQL表轉(zhuǎn)移數(shù)據(jù)的三種方式小結(jié)

    MySQL表轉(zhuǎn)移數(shù)據(jù)的三種方式小結(jié)

    本文主要介紹了MySQL表轉(zhuǎn)移數(shù)據(jù)的三種方式小結(jié),包括SQL命令,數(shù)據(jù)量不大的情況,直接使用SQL插入數(shù)據(jù)及使用Canal工具,具有一定的參考價值,感興趣的可以了解一下
    2025-02-02
  • Mysql效率優(yōu)化定位較低sql的兩種方式

    Mysql效率優(yōu)化定位較低sql的兩種方式

    通過慢查詢?nèi)罩径ㄎ荒切﹫?zhí)行效率較低的 SQL 語句,用 --log-slow-queries[=file_name] 選項啟動時, mysqld 會 寫一個包含所有執(zhí)行時間超過 long_query_time 秒的 SQL 語句的日志文件,通過查看這個日志文件定位效率較低的 SQL
    2015-10-10
  • MySQL 中查找含有目標(biāo)字段的表的方法

    MySQL 中查找含有目標(biāo)字段的表的方法

    這篇文章主要介紹了MySQL 中查找含有目標(biāo)字段的表的方法,即查找某個字段在哪個表中,這在一些場景中非常有用,需要的朋友可以參考下
    2015-06-06
  • MySQL5.7.10 安裝文檔教程詳解

    MySQL5.7.10 安裝文檔教程詳解

    這篇文章主要介紹了MySQL5.7.10 安裝文檔教程詳解,需要的朋友可以參考下
    2017-02-02
  • MySQL Order By Rand()效率分析

    MySQL Order By Rand()效率分析

    本文詳細(xì)解說了MySQL Order By Rand()效率優(yōu)化的方案,并給出了優(yōu)化的思路過程,是篇不可多得的MySQL Order By Rand()效率美文
    2012-07-07
  • mysql 5.7.18 Installer安裝下載圖文教程

    mysql 5.7.18 Installer安裝下載圖文教程

    這篇文章主要為大家詳細(xì)介紹了mysql 5.7.18 Installer安裝下載圖文教程,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-09-09
  • mysql 8.0.17 安裝與使用教程圖解

    mysql 8.0.17 安裝與使用教程圖解

    這篇文章主要介紹了mysql 8.0.17 安裝與使用教程圖解,本文圖文并茂給大家介紹的非常詳細(xì),具有一定的參考借鑒價值,需要的朋友可以參考下
    2019-08-08
  • MySQL中distinct與group by語句的一些比較及用法講解

    MySQL中distinct與group by語句的一些比較及用法講解

    這篇文章主要介紹了MySQL中distinct與group by的一些比較及用法講解,二者在查詢操作中的用法有很多相似之處,需要的朋友可以參考下
    2016-01-01
  • Windows7下Python3.4使用MySQL數(shù)據(jù)庫

    Windows7下Python3.4使用MySQL數(shù)據(jù)庫

    這篇文章主要為大家詳細(xì)介紹了Windows7下Python3.4使用MySQL數(shù)據(jù)庫,MySQL Community Server的安裝步驟,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-07-07

最新評論

连平县| 云南省| 通渭县| 宁阳县| 乐至县| 潞西市| 岗巴县| 枣强县| 河北区| 亳州市| 巴彦淖尔市| 阳江市| 靖安县| 当涂县| 黎城县| 临潭县| 垫江县| 南康市| 宝山区| 关岭| 剑阁县| 蒙城县| 革吉县| 湖口县| 河东区| 九龙县| 武邑县| 鄂州市| 龙胜| 浙江省| 银川市| 上蔡县| 五大连池市| 昌吉市| 沂源县| 筠连县| 聂拉木县| 灵璧县| 连南| 望城县| 北辰区|