EXPLAIN 執行計划詳解


 執行計划詳解

通過EXPLAIN關鍵分析的結果由以下列組成,接下來挨個分析每一個列

 

1.  ID列

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

根據ID的數值結果可以分成一下三種情況

l  id相同:執行順序由上至下

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

2. select_type列

Select_type:查詢的類型,

要是用於區別:普通查詢、聯合查詢、子查詢等的復雜查詢

類型如下

 

2.1.  SIMPLE

EXPLAIN select * from t1

簡單的 select 查詢,查詢中不包含子查詢或者UNION

2.2.     PRIMARY與SUBQUERY

PRIMARY:查詢中若包含任何復雜的子部分,最外層查詢則被標記為

SUBQUERY:在SELECT或WHERE列表中包含了子查詢

EXPLAIN

select t1.*,(select t2.id from t2 where t2.id = 1 ) from t1

 

2.3.     DERIVED

在FROM列表中包含的子查詢被標記為DERIVED(衍生)

MySQL會遞歸執行這些子查詢, 把結果放在臨時表里。

select t1.* from t1 ,(select t2.* from t2 where t2.id = 1 ) s2  where t1.id = s2.id

 

2.4.     UNION RESULT 與UNION

UNION:若第二個SELECT出現在UNION之后,則被標記為UNION;

UNION RESULT:從UNION表獲取結果的SELECT

#UNION RESULT ,UNION

EXPLAIN

select * from t1

UNION

select * from t2

3. table列

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

 

4.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

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

4.1.     System與const

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

Const:表示通過索引一次就找到了

const用於比較primary key或者unique索引。因為只匹配一行數據,所以很快

如將主鍵置於where列表中,MySQL就能將該查詢轉換為一個常量

4.2.     eq_ref

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

EXPLAIN

 SELECT * from t1,t2 where t1.id = t2.id

 

4.3.     Ref

 非唯一性索引掃描,返回匹配某個單獨值的所有行.

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

EXPLAIN

select count(DISTINCT col1) from t1 where col1 = 'ac'

 

或者

EXPLAIN

select col1 from t1 where col1 = 'ac'

 4.4.     Range

只檢索給定范圍的行,使用一個索引來選擇行。key 列顯示使用了哪個索引

一般就是在你的where語句中出現了between、<、>、in等的查詢

這種范圍掃描索引掃描比全表掃描要好,因為它只需要開始於索引的某一點,而結束語另一點,不用掃描全部索引。

 

EXPLAIN select * from t1 where id BETWEEN 30 and 60

EXPLAIN select * from t1 where id in(1,2)

4.5.     Index

當查詢的結果全為索引列的時候,雖然也是全部掃描,但是只查詢的索引庫,而沒有去查詢

數據。

EXPLAIN

select c2 from testdemo

4.6.     All

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

 

5.   possible_keys 與Key

possible_keys:可能使用的key

Key:實際使用的索引。如果為NULL,則沒有使用索引

查詢中若使用了覆蓋索引,則該索引和查詢的select字段重疊

 

EXPLAIN select col1,col2 from t1

其中key和possible_keys都可以出現null的情況

6.    key_len

Key_len表示索引中使用的字節數,可通過該列計算查詢中使用的索引的長度。在不損失精確性的情況下,長度越短越好

key_len顯示的值為索引字段的最大可能長度,並非實際使用長度,即key_len是根據表定義計算而得,不是通過表內檢索出的

l  key_len表示索引使用的字節數,

l  根據這個值,就可以判斷索引使用情況,特別是在組合索引的時候,判斷所有的索引字段是否都被查詢用到。

l  char和varchar跟字符編碼也有密切的聯系,

latin1占用1個字節,gbk占用2個字節,utf8占用3個字節。(不同字符編碼占用的存儲空間不同)

字符類型-索引字段為char類型+不可為Null時

 

CREATE TABLE `s1` (

  `id` int(11) NOT NULL AUTO_INCREMENT,

  `name` char(10) NOT NULL,

  `addr` varchar(20) DEFAULT NULL,

  PRIMARY KEY (`id`),

  KEY `name` (`name`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8;

 

explain select * from s1 where name='enjoy';

name這一列為char(10),字符集為utf-8占用3個字節

Keylen=10*3

 

字符類型-索引字段為char類型+允許為Null時

 

CREATE TABLE `s2` (

  `id` int(11) NOT NULL AUTO_INCREMENT,

  `name` char(10) DEFAULT NULL,

  `addr` varchar(20) DEFAULT NULL,

  PRIMARY KEY (`id`),

  KEY `name` (`name`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8;

 

explain select * from s2 where name='enjoyedu';

name這一列為char(10),字符集為utf-8占用3個字節,外加需要存入一個null值

Keylen=10*3+1(null) 結果為31

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

 

CREATE TABLE `s3` (

  `id` int(11) NOT NULL AUTO_INCREMENT,

  `name` varchar(10) NOT NULL,

  `addr` varchar(20) DEFAULT NULL,

  PRIMARY KEY (`id`),

  KEY `name` (`name`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8;

 

explain select * from s3 where name='enjoyeud';

Keylen=varchar(n)變長字段+不允許Null=n*(utf8=3,gbk=2,latin1=1)+2

 

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

 

CREATE TABLE `s3` (

  `id` int(11) NOT NULL AUTO_INCREMENT,

  `name` varchar(10) NOT NULL,

  `addr` varchar(20) DEFAULT NULL,

  PRIMARY KEY (`id`),

  KEY `name` (`name`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8;

 

explain select * from s3 where name='enjoyeud';

 

 

Keylen=varchar(n)變長字段+允許Null=n*(utf8=3,gbk=2,latin1=1)+1(NULL)+2

 

 

6.2.     數值類型

 

6.3.日期和時間

datetime類型在5.6中字段長度是5個字節

datetime類型在5.5中字段長度是8個字節

復合索引有最左前綴的特性,如果復合索引能全部使用上,則是復合索引字段的索引長度之和,這也可以用來判定復合索引是否部分使用,還是全部使用。

7. Ref

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

 

8. Rows

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

 

9. Extra

包含不適合在其他列中顯示但十分重要的額外信息。

9.3. Using index

表示相應的select操作中使用了覆蓋索引(Covering Index),避免訪問了表的數據行,效率不錯!

如果同時出現using where,表明索引被用來執行索引鍵值的查找;

如果沒有同時出現using where,表明索引用來讀取數據而非執行查找動作

 


免責聲明!

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



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