SQL優化經歷

參考:https://mp.weixin.qq.com/s/NJW8_Rjd-dCSmGAZ-vMGZQmysql

用的數據庫是mysql5.6,下面簡單的介紹下場景sql

課程表:數據庫

數據100條優化

學生表:3d

數據70000條orm

學生成績表SC:cdn

數據70w條blog

查詢目的:索引

查找語文考100分的考生it

查詢語句:

執行時間:30248.271s

爲何這麼慢?先來查看下查詢計劃:

發現沒有用到索引,type全是ALL,那麼首先想到的就是創建一個索引,創建索引的字段固然是在where條件的字段。

先給sc表的c_id和score建個索引

再次執行上述查詢語句,時間爲: 1.054s

快了3w多倍,大大縮短了查詢時間,看來索引能極大程度的提升查詢效率,看來建索引頗有必要,不少時候都忘記建索引了,數據量小的的時候壓根沒感受,這優化感受挺爽。

可是1s的時間仍是太長了,還能進行優化嗎,仔細看執行計劃:

查看優化後的sql:

補充:這裏有網友問怎麼查看優化後的語句

方法以下:

在命令窗口執行

有type=all

按照我以前的想法,該sql的執行的順序應該是先執行子查詢

耗時:0.001s

獲得以下結果:

而後再執行

耗時:0.001s

這樣就是至關快了啊,Mysql居然不是先執行裏層的查詢,而是將sql優化成了exists子句,並出現了EPENDENT SUBQUERY,

mysql是先執行外層查詢,再執行裏層的查詢,這樣就要循環70007*11=770077次。

那麼改用鏈接查詢呢?

這裏爲了從新分析鏈接查詢的狀況,先暫時刪除索引sc_c_id_index,sc_score_index

執行時間是:0.057s

效率有所提升,看看執行計劃:

這裏有連表的狀況出現,我猜測是否是要給sc表的s_id創建個索引

CREATE index sc_s_id_index on SC(s_id);

show index from SC

在執行鏈接查詢

時間: 1.076s,居然時間還變長了,什麼緣由?查看執行計劃:

優化後的查詢語句爲:

貌似是先作的鏈接查詢,再執行的where過濾

回到前面的執行計劃:

這裏是先作的where過濾,再作連表,執行計劃還不是固定的,那麼咱們先看下標準的sql執行順序:

正常狀況下是先join再where過濾,可是咱們這裏的狀況,若是先join,將會有70w條數據發送join作操,所以先執行where

過濾是明智方案,如今爲了排除mysql的查詢優化,我本身寫一條優化後的sql

即先執行sc表的過濾,再進行錶鏈接,執行時間爲:0.054s

和以前沒有建s_id索引的時間差很少

查看執行計劃:

先提取sc再連表,這樣效率就高多了,如今的問題是提取sc的時候出現了掃描表,那麼如今能夠明確須要創建相關索引

再執行查詢:

執行時間爲:0.001s,這個時間至關靠譜,快了50倍

執行計劃:

咱們會看到,先提取sc,再連表,都用到了索引。

那麼再來執行下sql

執行時間0.001s

執行計劃:

這裏是mysql進行了查詢語句優化,先執行了where過濾,再執行鏈接操做,且都用到了索引。

總結

一、mysql嵌套子查詢效率確實比較低

二、能夠將其優化成鏈接查詢

三、創建合適的索引

四、學會分析sql執行計劃,mysql會對sql進行優化,因此分析執行計劃很重要

相關文章
相關標籤/搜索