MySQL優化之explain

 在日常的MYSQL優化中我們常常看到這樣一個關鍵詞:explain,例如這種:

EXPLAIN SELECT * FROM Cloud_Order WHERE money > 10;

       explain是什麼呢?使用 EXPLAIN 關鍵字可以模擬優化器執行SQL查詢語句,從而知道MySQL是如何處理你的SQL語句的。這可以幫你分析你的查詢語句或是表結構的性能瓶頸。通過explain命令可以得到:

  1. 表的讀取順序

  2. 數據讀取操作的操作類型

  3. 哪些索引可以使用

  4. 哪些索引被實際使用

  5. 表之間的引用

  6. 每張表有多少行被優化器查詢


       首先讓我們來看看使用EXPLAIN輸入的結果
5e.jpg

       結果顯示輸出了結果一堆字段和對應的值,但是這些字段是什麼意思?對應的值又是什麼呢?如何通過這些字段來分析到SQL的性能並做出優化呢?別急,下面我們就一起來一一分析。

EXPLANIN字段分析


  • id : SELECT識別符。這是SELECT的查詢序列號


  • select_typeSELECT類型,可以爲以下任何一種

    ·SIMPLE:簡單SELECT(不使用UNION或子查詢)


    ·PRIMARY:最外面的SELECT


    ·UNION:UNION中的第二個或後面的SELECT語句


    ·DEPENDENT UNION:UNION中的第二個或後面的SELECT語句,取決於外面的查詢


    ·UNION RESULT:UNION 的結果


    ·SUBQUERY:子查詢中的第一個SELECT


    ·DEPENDENT SUBQUERY:子查詢中的第一個SELECT,取決於外面的查詢


    ·DERIVED:導出表的SELECT(FROM子句的子查詢)


  • table:顯示這一行的數據是關於哪張表的


  • type:這是最重要的字段之一,顯示查詢使用了何種類型。從最好到最差的連接類型爲systemconsteq_regrefrangeindexALL。下面給出各種類型,按照從最佳類型到最壞類型進行排序:


    ·systemconst:可以將查詢的變量轉爲常量.  id=1; id 主鍵或唯一鍵.


    ·eq_ref:訪問索引,返回某單一行的數據.(通常在聯接時出現,查詢使用的索引爲主鍵或惟一鍵)


    ·ref:訪問索引,返回某個值的數據.(可以返回多行) 通常使用=時發生


    ·range:這個連接類型使用索引返回一個範圍中的行,比如使用>或<查找東西,並且該字段上建有索引時發生的情況(注:不一定好於index)


    ·index:以索引的順序進行全表掃描,優點是不用排序,缺點是還要全表掃描


    ·ALL:全表掃描,應該儘量避免


  • possible_keys:顯示可能應用在這張表中的索引。如果爲空,沒有可能的索引。可以爲相關的域從WHERE語句中選擇一個合適的語句


  • key:實際使用的索引。如果爲NULL,則沒有使用索引。MYSQL很少會選擇優化不足的索引,此時可以在SELECT語句中使用USE INDEXindex)來強制使用一個索引或者用IGNORE INDEXindex)來強制忽略索引


  • key_len:使用的索引的長度。在不損失精確性的情況下,長度越短越好


  • ref:顯示索引的哪一列被使用了,如果可能的話,是一個常數


  • rowsMySQL認爲必須檢索的用來返回請求數據的行數


  • filtered:顯示了通過條件過濾出的行數的百分比估計值。


  • Extra:關於MYSQL如何解析查詢的額外信息,主要有以下幾種


    ·DistinctMySQL發現第1個匹配行後,停止爲當前的行組合搜索更多的行。


    ·range checked for each record (index map: #):MySQL沒有發現好的可以使用的索引,但發現如果來自前面的表的列值已知,可能部分索引可以使用。


    ·Using index:只用到索引,可以避免訪問表.


    ·Using tmporary:用到臨時表


    ·Using where:使用到where來過慮數據. 不是所有的where clause都要顯示using where. 如以=方式訪問索引.


    ·Using filesortMySQL需要額外的一次傳遞,以找出如何按排序順序檢索行。

explain實踐

       說了這麼多,實踐才能出真知。下面我們通過一個簡單的例子來優化我們一些不堪的SQL。
       首先我們還是一張數據表舉例。表結構如下。

5ee.jpg

這是一張典型的訂單表,其他字段我們可以省略不看,我們可以只看一個money字段,這基本是訂單表都會用到的字段。由於時間關係,事先我已經爲這個表準備了一堆模擬數據。


5eee.jpg

       從上圖可以看出,表中已經有一萬條數據,下面我們來寫一個根據money條件來查詢訂單的SQL。

5eeee.jpg

       只能說上圖的結果不盡人意。讓我們回到之前explain字段的分析,其中type字段的值是ALL,按照分析來說,這個表用了全表搜索,我們應儘量避免!!!再看rows字段,值是16242,天啊!!所有記錄都去請求了,那慢是有原因的。

       好了,通過上面的數據分析,我們可以去想一下,money字段是否能加上索引來提升查詢速度呢?因爲上述結果中好像是沒用到索引的。話不多說,我們來爲money字段加上索引

6e.jpg

        加上索引之後,我們再用剛剛的EXPLAIN語句執行一下,見證奇蹟的時候到了!

7e.jpg

      經過加上索引之後,相同的sql語句,得出的結果完全不一樣,type字段變成了range,我們也看到key顯示了money,證明了索引值被用上了。更重要的是rows字段變成了785,跟原來相比少了不知道多少,可想而知性能有了多大的提高!

       好了,上面就是explain的簡單實踐。

總結

       通過explain,我們可以對原有的sql做進行不同的分析,可以分析出有沒有使用到索引,可以知道這是一條快SQL還是慢SQL,EXPLAIN的作用就是幫我們顯示出SQL的性能瓶頸和各項可能的結果,這對於我們去優化MSQL的查詢有着重要的意義,根絕EXPALIN字段返回不同的結果,我們就能對原有的慢SQL進行改造了。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章