Mysql優化之Explain查詢計划查看


 

我們經常說到mysql優化,優化中一種常見的方式就是對於經常查詢的字段創建索引。那么mysql中有哪些索引類型呢?

一、索引分類
1、普通索引:即一個索引只包含單個列,一個表可以有多個單列索引

2、唯一索引:索引列的值必須唯一,但允許有空值

3、復合索引:即一個索引包含多個列

4、聚簇索引(聚集索引):並不是一種單獨的索引類型,而是一種數據存儲方式。具體細節取決於不同的實現,InnoDB的聚簇索引其實就是在同一個結構中保存了B-Tree索引(技術上來說是B+Tree)和數據行。

5、非聚簇索引:不是聚簇索引,就是非聚簇索引

 

二、基本語法

查看索引
SHOW INDEX FROM table_name

創建索引
CREATE [UNIQUE ] INDEX indexName ON mytable(columnname(length));
ALTER TABLE 表名 ADD [UNIQUE ] INDEX [indexName] ON (columnname(length))

刪除索引
DROP INDEX [indexName] ON mytable;

上面講了創建索引的基本語法,現在處理講一下如何查看執行計划。


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

執行計划的作用:1、表的讀取順序,2、數據讀取操作的操作類型/   3、哪些索引可以使用,哪些索引被實際使用    4、表之間的引用    5 、每張表有多少行被優化器查詢

執行計划包含的信息有:

 

執行計划-ID

select查詢的序列號,包含一組數字,表示查詢中執行select子句或操作表的順序

有三種情況:
(1)、id相同,執行順序由上至下
(2)、id不同,如果是子查詢,id的序號會遞增,id值越大優先級越高,越先被執行
(3)、id相同不同,同時存在

執行計划-select_type:查詢的類型,主要是用於區別,普通查詢、聯合查詢、子查詢等的復雜查詢

 

 


執行計划-type
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

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

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

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

range:只檢索給定范圍的行,使用一個索引來選擇行。key 列顯示使用了哪個索引,一般就是在你的where語句中出現了between、<、>、in等的查詢
              這種范圍掃描索引掃描比全表掃描要好,因為它只需要開始於索引的某一點,而結束語另一點,不用掃描全部索引。

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

執行計划-possible_keys : 實際使用的索引。如果為NULL,則沒有使用索引,查詢中若使用了覆蓋索引,則該索引和查詢的select字段重疊

執行計划-key_len :表示索引中使用的字節數,可通過該列計算查詢中使用的索引的長度。在不損失精確性的情況下,長度越短越好
                              key_len顯示的值為索引字段的最大可能長度,並非實際使用長度,即key_len是根據表定義計算而得,不是通過表內檢索出的

                             根據這個值,就可以判斷索引使用情況,特別是在組合索引的時候,判斷所有的索引字段是否都被查詢用到。
                              char和varchar跟字符編碼也有密切的聯系,
                              latin1占用1個字節,gbk占用2個字節,utf8占用3個字節。(不同字符編碼占用的存儲空間不同)

 

 

 

 

 

 

 

 

字符類型:索引字段為char + 不為 null:

 

字符類型:索引字段為char + 允許為 null:

 

索引字段為varchar類型+不可為Null時:

 


索引字段為varchar類型+允許為Null時:

 

 

 

 

 

整數/浮點數/時間類型的索引長度 :NOT NULL=字段本身的字段長度,NULL=字段本身的字段長度+1(因為需要有是否為空的標記,這個標記需要占用1個字節)
                                                       datetime類型在5.6中字段長度是5個字節,datetime類型在5.5中字段長度是8個字節

key_len 總結:
變長字段需要額外的2個字節(VARCHAR值保存時只保存需要的字符數,另加一個字節來記錄長度(如果列聲明的長度超過255,則使用兩個字節),所以VARCAHR索引長度計算時候要加2),固定長度字段不需要額外的字節。
而NULL都需要1個字節的額外空間,所以索引字段最好不要為NULL,因為NULL讓統計更加復雜並且需要額外的存儲空間。
復合索引有最左前綴的特性,如果復合索引能全部使用上,則是復合索引字段的索引長度之和,這也可以用來判定復合索引是否部分使用,還是全部使用。

 

執行計划-ref : 顯示索引的哪一列被使用了,如果可能的話,是一個常數。哪些列或常量被用於查找索引列上的值

執行計划-rows:根據表統計信息及索引選用情況,大致估算出找到所需的記錄所需要讀取的行數

執行計划-Extra:包含不適合在其他列中顯示但十分重要的額外信息

 

 

Using filesort 說明mysql會對數據使用一個外部的索引排序,而不是按照表內的索引順序進行讀取。MySQL中無法利用索引完成的排序操作稱為“文件排序”
Using temporary:使了用臨時表保存中間結果,MySQL在對查詢結果排序時使用臨時表。常見於排序 order by 和分組查詢 group by

USING index :表示相應的select操作中使用了覆蓋索引(Covering Index),避免訪問了表的數據行,效率不錯,如果同時出現using where,表明索引被用來執行索引鍵值的查找,
如果沒有同時出現using where,表明索引用來讀取數據而非執行查找動作

 

 

 

    

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM