MySQL作為存儲(chǔ)數(shù)據(jù)的工具,它有自己的書(shū)寫(xiě)語(yǔ)言,相信很多小伙伴經(jīng)過(guò)系統(tǒng)學(xué)習(xí)之后,能夠熟練掌握數(shù)據(jù)庫(kù)定義語(yǔ)言、數(shù)據(jù)庫(kù)操縱語(yǔ)言的語(yǔ)序。但在真正使用SQL過(guò)程中,通常要考慮SQL語(yǔ)句的執(zhí)行效率,特別是查詢語(yǔ)句的效率就需要我們了解SQL語(yǔ)句的執(zhí)行順序,這樣才能寫(xiě)出更好地SQL語(yǔ)句,今天就大致梳理一下MySQL查詢語(yǔ)句的執(zhí)行順序。
n首先SQL語(yǔ)句的基本語(yǔ)法如下:
1、select 查詢字段1,查詢字段2,聚合函數(shù),distinct
2、from 表名
3、join on 表名
4、where 條件
5、group by 分組排列
6、having 條件
7、order by 排序(升序降序)
8、limit 結(jié)果限定
n按照以上書(shū)寫(xiě)順序,完整的執(zhí)行順序應(yīng)該是這樣:
1、from子句識(shí)別查詢表的數(shù)據(jù);
2、join on/union用于連接多表數(shù)據(jù);
3、where子句基于指定的條件對(duì)記錄進(jìn)行篩選;
4、group by 子句將數(shù)據(jù)劃分成多個(gè)組別,如按性別男、女分組;
5、有聚合函數(shù)時(shí),要使用聚集函數(shù)進(jìn)行數(shù)據(jù)計(jì)算;
6、Having子句篩選滿足第二條件的數(shù)據(jù);
7、執(zhí)行select語(yǔ)句進(jìn)行字段篩選
8、篩選重復(fù)數(shù)據(jù);
9、對(duì)數(shù)據(jù)進(jìn)行排序;
10、執(zhí)行l(wèi)imit進(jìn)行結(jié)果限定。
n如果還不能理解通過(guò)下面的例子就能一目了然:
uselect 查詢字段 from 表列表名/視圖列表名 where 條件.
執(zhí)行順序:先f(wàn)rom再where select
uselect 查詢字段 from 表列表名/視圖列表名 where 條件 group by (列列表) having 條件
執(zhí)行順序:先f(wàn)rom再where再group by 再having select
uselect 查詢字段 from 表列表名/視圖列表名 where 條件 group by (列列表) having 條件 order by 列列表
執(zhí)行順序:先f(wàn)rom再where再group by再having再select order by
uselect 查詢字段 from 表1 join 表2 on 表1.列1=表2.列1...join 表n on 表n.列1=表(n-1).列1 where 表1.條件 and 表2.條件...表n.
執(zhí)行順序:先f(wàn)rom 再join再where select
n就是因?yàn)橛袌?zhí)行順序的限制,在書(shū)寫(xiě)SQL語(yǔ)句時(shí)需要注意一下幾點(diǎn):
uSQL語(yǔ)句是從from開(kāi)始執(zhí)行,而不是從select。MySQL在執(zhí)行SQL查詢語(yǔ)句時(shí),首先是將數(shù)據(jù)從硬盤(pán)加載數(shù)據(jù)緩沖區(qū)中,以便對(duì)這些數(shù)據(jù)進(jìn)行操作;
uSelect是在from和group by 之后執(zhí)行,這就導(dǎo)致了無(wú)法在where中使用select中設(shè)置的字段別名作為查詢條件。如需要查詢男學(xué)生的總成績(jī)并要升序排列:select sum(score) as “成績(jī)總和” from score where sex=“男” order by sum(score);
u聚合函數(shù)的計(jì)算在where子句之后,所以在where子句中就不能使用聚合函數(shù);
uUnion是排在Order by 之前的,雖然數(shù)據(jù)庫(kù)允許SQL語(yǔ)句對(duì)UNION段中的子查詢或者派生表進(jìn)行排序,但這并不能說(shuō)明在union操作過(guò)后仍保持排序后的順序。如下圖:
u在MySQL中SQL的邏輯查詢時(shí)根據(jù)以上描述進(jìn)行的,但MySQL可能并不完全會(huì)按照邏輯查詢處理方式進(jìn)行查詢。MySQL有2個(gè)組件:
a)分析SQL語(yǔ)句的Parser;
b)優(yōu)化器Optimizer;
MySQL在執(zhí)行查詢之前都會(huì)選擇一條自認(rèn)為的查詢方案去執(zhí)行,獲取查詢結(jié)果。一般情況下都能計(jì)算出的查詢方案;
u存在索引時(shí),優(yōu)化器優(yōu)先使用索引的插敘條件,當(dāng)索引為多個(gè)時(shí),優(yōu)化器會(huì)直接選擇效率的索引去執(zhí)行。