了解select語(yǔ)句的執(zhí)行順序有助于更好的理解查詢(xún)的子句和優(yōu)化sql查詢(xún)。自己以前也是很亂,今天仔細(xì)了解一下,就趁熱打鐵分享一下。
mysql中select查詢(xún)語(yǔ)句的執(zhí)行順序遵循以下過(guò)程
#FROM ...,...-> ON -> (LEFT/RIGNT JOIN) -> WHERE -> GROUP BY -> HAVING -> SELECT -> DISTINCT -> ORDER BY -> LIMIT
我們來(lái)簡(jiǎn)單分析一下
一、select是先執(zhí)行FROM這一步的,如果是多表連接查詢(xún),還會(huì)分出以下幾個(gè)步驟
????1. 通過(guò)join進(jìn)行表連接求得笛卡爾積,相當(dāng)于得到虛擬表(virtual table)表1-1
????2. 通過(guò)on條件的篩選,在表1-1的基礎(chǔ)上進(jìn)行篩選得到表1-2
????3. 添加外部行,如果連接是外連接的話(huà),如果主表有些行的數(shù)據(jù)沒(méi)匹配上,就被稱(chēng)為外部行,在這時(shí)加上,此時(shí)得到表1-3
到這里完成前兩個(gè)表的連接,如果是多個(gè)表的話(huà),需要重復(fù)上面的步驟,直到所有表被處理完。
二、我們拿到第一個(gè)步驟的最終結(jié)果表1之后,執(zhí)行WHERE階段,會(huì)對(duì)表1進(jìn)行篩選得到表2
三、之后進(jìn)入GROUP和HAVING階段,先執(zhí)行GROUP BY 進(jìn)行分組得到表3,之后再根據(jù)HAVING對(duì)表三進(jìn)行篩選得到表4
四、完成之后進(jìn)入select,前面的步驟都是為獲取結(jié)果做準(zhǔn)備,直到這里,執(zhí)行SELECT DISTINCT,得到表5-1和表5-2,自我感覺(jué)表5-1就是表4,畢竟已經(jīng)將所有限制條件篩選完了,DISTINCT清除重復(fù)項(xiàng)得到表5-2
五、我們得到想要的數(shù)據(jù)后,就要去看以什么方式呈現(xiàn),先根據(jù)ORDER BY 進(jìn)行排序得到表6
六、再根據(jù)limit去限制輸出的范圍,至此查詢(xún)結(jié)束,將結(jié)果輸出。
看完分析,試著看看下面的語(yǔ)句執(zhí)行順序排個(gè)序
SELECT DISTINCT player_id, player_name, count(*) as num
FROM player JOIN team ON player.team_id = team.team_id
WHERE height > 1.80
GROUP BY player.team_id
HAVING num > 2 ?
ORDER BY num DESC
LIMIT 2
(5,1,2,3,4,6,7)
雖然優(yōu)化器會(huì)幫助我們優(yōu)化能夠優(yōu)化的查詢(xún),但是我們最好還是盡量避免多表連接和復(fù)雜語(yǔ)句,這種操作不僅耗時(shí)而且費(fèi)空間,了解select的執(zhí)行過(guò)程后,我們?cè)趯?xiě)查詢(xún)的時(shí)候可以根據(jù)此來(lái)注意一下,盡量?jī)?yōu)化查詢(xún)語(yǔ)句,雖然沒(méi)有索引來(lái)的直接,但是不同的查詢(xún)方式有的時(shí)候還是能起大作用的。