1. 程式人生 > >Mysql學習-03 索引優化分析--效能分析

Mysql學習-03 索引優化分析--效能分析

效能分析 -->Explain工具:

  1.    執行計劃 

        使用EXPLAIN關鍵字可以模擬優化器執行SQL查詢語句,從而知道MySQL是如何處理你的SQL語句的。分析你的查詢語句或是表結構的效能瓶頸。

    2.用途

      表的讀取順序,哪些索引可以使用,資料讀取操作的操作型別,哪些索引被實際使用,表之間的引用,每張表有多少行被物理查詢

    3.使用:

      Explain + SQL語句

     

      各欄位解釋:

       1. id:select查詢的序列號,包含一組數字,表示查詢中執行select子句或操作表的順序
        三種情況

            
            id相同,執行順序由上至下

            
           id不同,如果是子查詢,id的序號會遞增,id值越大優先順序越高,越先被執行

           
           id相同不同,同時存在 

           id如果相同,可以認為是一組,從上往下順序執行;在所有組中,id值越大,優先順序越高,越先執行,衍生 = DERIVED
       關注點
          id號每個號碼,表示一趟獨立的查詢。一個sql 的查詢趟數越少越好。

       2.select_type:查詢的型別,主要是用於區別普通查詢、聯合查詢、子查詢等的複雜查詢

         2.1 SIMPLE -->簡單的 select 查詢,查詢中不包含子查詢或者UNION

         

        2.2 PRIMARY -->查詢中若包含任何複雜的子部分,最外層查詢則被標記為Primary 

         

        2.3 DERIVED -->在FROM列表中包含的子查詢被標記為DERIVED(衍生) MySQL會遞迴執行這些子查詢, 把結果放在臨時表裡。 

        

       2.4 SUBQUERY -->在SELECT或WHERE列表中包含了子查詢 

        

      2.5 DEPENDENT SUBQUERY -->在SELECT或WHERE列表中包含了子查詢,子查詢基於外層 

       

      2.6 UNCACHEABLE SUBQUREY -->無法被快取的子查詢

       

        

        2.7 UNION -->若第二個SELECT出現在UNION之後,則被標記為UNION; 若UNION包含在FROM子句的子查詢中,外層SELECT將被標記為:DERIVED 

         

        2.8 UNION RESULT--> 從UNION表獲取結果的SELECT 

         

       3.table 顯示這一行的資料是關於哪張表的

       4.type (重點*)

        4.1訪問型別排列 

          type顯示的是訪問型別,是較為重要的一個指標,結果值從最好到最壞依次是: system > const > eq_ref > ref > fulltext > ref_or_null > index_merge > unique_subquery > index_subquery > range > index > ALL 

        關注:system>const>eq_ref>ref>range>index>ALL 一般來說,得保證查詢至少達到range級別,最好能達到ref。 

       4.2顯示查詢使用了何種型別 -->從最好到最差依次是:system>const>eq_ref>ref>range>index>AL

       4.2.1:system -->表只有一行記錄(等於系統表),這是const型別的特列,平時不會出現,這個也可以忽略不計 

       4.2.2:const-->表示通過索引一次就找到了,const用於比較primary key或者unique索引。因為只匹配一行資料,所以很快 如將主鍵置於where列表中,MySQL就能將該查詢轉換為一個常量

        

       4.2.3:eq_ref -->唯一性索引掃描,對於每個索引鍵,表中只有一條記錄與之匹配。常見於主鍵或唯一索引掃描

        

      4.2.4:ref -->非唯一性索引掃描,返回匹配某個單獨值的所有行. 本質上也是一種索引訪問,它返回所有匹配某個單獨值的行,然而, 它可能會找到多個符合條件的行,所以他應該屬於查詢和掃描的混合體 

       

       

     4.2.5:index-->Full Index Scan,index與ALL區別為index型別只遍歷索引樹。這通常比ALL快,因為索引檔案通常比資料檔案小.(也就是說雖然all和Index都是讀全表,但index是從索引中讀取的,而all是從硬碟中讀的

      

    4.2.6:all --> Full Table Scan,將遍歷全表以找到匹配的行

      

     

   4.2.7:index_merge--> 在查詢過程中需要多個索引組合使用,通常出現在有 or 的關鍵字的sql中

     

   4.2.8:ref_or_null-->對於某個欄位既需要關聯條件,也需要null值得情況下。查詢優化器會選擇用ref_or_null連線查詢。

     

   4.2.9:index_subquery-->利用索引來關聯子查詢,不再全表掃描。

     

     

     

    4.2.9:unique_subquery -->該聯接型別類似於index_subquery。 子查詢中的唯一索引 

     

   備註:一般來說,得保證查詢至少達到range級別,最好能達到ref。 

   5.possible_keys -->顯示可能應用在這張表中的索引,一個或多個。 查詢涉及到的欄位上若存在索引,則該索引將被列出,但不一定被查詢實際使用 .

   6.key -->實際使用的索引。如果為NULL,則沒有使用索引;查詢中若使用了覆蓋索引,則該索引和查詢的select欄位重疊.

     

  7.key_len -->表示索引中使用的位元組數,可通過該列計算查詢中使用的索引的長度.key_len欄位能夠幫你檢查是否充分的利用上了索引.

   

  如何計算
    1 、先看索引上欄位的型別+長度比如 int=4 ;  varchar(20) =20 ; char(20) =20  
    2  、如果是varchar或者char這種字串欄位,視字符集要乘不同的值,比如utf-8  要乘 3,GBK要乘2,
    3 、varchar這種動態字串要加2個位元組
    4、 允許為空的欄位要加1個位元組

   

    第一組:key_len=age的位元組長度+name的位元組長度=4+1  + ( 20*3+2)=5+62=67
    第二組: key_len=age的位元組長度=4+1=5 

  8.ref -->顯示索引的哪一列被使用了,如果可能的話,是一個常數。哪些列或常量被用於查詢索引列上的值

     

 9. rows -->rows列顯示MySQL認為它執行查詢時必須檢查的行數。越少越好

   

   

10.Extra -->包含不適合在其他列中顯示但十分重要的額外資訊

  10.1:Using filesort 
          說明mysql會對資料使用一個外部的索引排序,而不是按照表內的索引順序進行讀取。 MySQL中無法利用索引完成的排序操作稱為“檔案排序”

  出現filesort的情況:

  

  優化後,不再出現filesort的情況:

 

 查詢中排序的欄位,排序欄位若通過索引去訪問將大大提高排序速度

 10.2 Using temporary 
  使了用臨時表儲存中間結果,MySQL在對查詢結果排序時使用臨時表。常見於排序 order by 和分組查詢 group by。

 優化前存在 using  temporary 和 using  filesort 

 

優化前存在 using  temporary 和 using  filesort 不在,效能發生明顯變化:

10.3 USING index
     表示相應的select操作中使用了覆蓋索引(Covering Index),避免訪問了表的資料行,效率不錯! 如果同時出現using where,表明索引被用來執行索引鍵值的查詢; 如果沒有同時出現using where,表明索引只是用來讀取資料而非利用索引執行查詢。
  覆蓋索引(Covering Index):索引是高效找到行的一個方法,但是一般資料庫也能使用索引找到一個列的資料,因此它不必讀取整個行。畢竟索引葉子節點儲存了它們索引的資料;當能通過讀取索引就可以得到想要的資料,那就不需要讀取行了。一個索引包含了(或覆蓋了)[select子句]與查詢條件[Where子句]中所有需要的欄位就叫做覆蓋索引。
注意:
   如果要使用覆蓋索引,一定要注意select列表中只取出需要的列,不可select *,
   因為如果將所有欄位一起做索引會導致索引檔案過大,查詢效能下降。

10.4 Using where --> 表明使用了where過濾

10.5 using join buffer -->使用了連線快取:

10.6 impossible where --> where子句的值總是false,不能用來獲取任何元組 

10.7 select tables optimized away
      在沒有GROUPBY子句的情況下,基於索引優化MIN/MAX操作或者 對於MyISAM儲存引擎優化COUNT(*)操作,不必等到執行階段再進行計算, 查詢執行計劃生成的階段即完成優化。  

在innodb中:

在Myisam中: