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

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

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

前言

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

一、理論順序

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

  • FROM

  • ON

  • JOIN

  • WHERE

  • GROUP BY

  • CUBE | ROLLUP

  • HAVING

  • SELECT

  • DISTINCT

  • ORDER BY

  • LIMIT

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

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

    因?yàn)榇翱诤瘮?shù)在 SELECT 步驟執(zhí)行,而這步是在 WHERE 和 GROUP BY 之后

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

    不可以,因?yàn)?GROUP BY 在 WHERE 之后執(zhí)行

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

    可以,因?yàn)?ORDER BY 在 GROUP BY 之后。

二、代碼示例

學(xué)生表

成績(jī)

查詢語(yǔ)句

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

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í)行過(guò)程

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

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

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

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

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

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

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

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

  • 添加外部行

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

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

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

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

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

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

  • 分組

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

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

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

  • 處理 SELECT 列表

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

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

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

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

  • LIMIT 子句

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

四、注意

上面所討論的順序皆為理論上的執(zhí)行順序,實(shí)際上數(shù)據(jù)庫(kù)引擎并不是通過(guò)連接、過(guò)濾和分組來(lái)運(yùn)行查詢,因?yàn)樗鼘?shí)現(xiàn)了一系列優(yōu)化來(lái)提升查詢速度(不影響最終的返回結(jié)果)。數(shù)據(jù)庫(kù)引擎可能會(huì)為了提高查詢的速度把一些過(guò)濾條件進(jìn)行提前,當(dāng)然前提是不會(huì)對(duì)返回的結(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 = "天津"

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

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

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

相關(guān)文章

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

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

    這篇文章主要介紹了MySQL線上死鎖分析實(shí)戰(zhàn),文章內(nèi)容分析的很清楚,有對(duì)于這方面不懂的同學(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工具,具有一定的參考價(jià)值,感興趣的可以了解一下
    2025-02-02
  • Mysql效率優(yōu)化定位較低sql的兩種方式

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

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

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

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

    MySQL5.7.10 安裝文檔教程詳解

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

    MySQL Order By Rand()效率分析

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

    mysql 5.7.18 Installer安裝下載圖文教程

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

    mysql 8.0.17 安裝與使用教程圖解

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

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

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

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

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

最新評(píng)論

德清县| 青河县| 田林县| 思茅市| 枝江市| 塔城市| 阜宁县| 筠连县| 常州市| 鱼台县| 开封县| 鄂伦春自治旗| 彝良县| 广州市| 滨州市| 郑州市| 环江| 泰安市| 浑源县| 固始县| 洪洞县| 新兴县| 澄城县| 荆州市| 溆浦县| 米泉市| 大兴区| 婺源县| 平凉市| 辽宁省| 乐安县| 乡城县| 聂拉木县| 漳浦县| 青川县| 黄梅县| 金阳县| 嘉黎县| 会宁县| 崇阳县| 井研县|