經過EXPLAIN關鍵分析的結果由如下列組成,接下來挨個分析每個列編碼
ID列:描述select查詢的序列號,包含一組數字,表示查詢中執行select子句或操做表的順序spa
根據ID的數值結果能夠分紅一下三種狀況3d
l id相同:執行順序由上至下blog
l id不一樣:若是是子查詢,id的序號會遞增,id值越大優先級越高,越先被執行遞歸
Select_type:查詢的類型,索引
要是用於區別:普通查詢、聯合查詢、子查詢等的複雜查詢utf-8
類型以下字符編碼
EXPLAIN select * from t1table
簡單的 select 查詢,查詢中不包含子查詢或者UNIONclass
PRIMARY:查詢中若包含任何複雜的子部分,最外層查詢則被標記爲
SUBQUERY:在SELECT或WHERE列表中包含了子查詢
EXPLAIN
select t1.*,(select t2.id from t2 where t2.id = 1 ) from t1
在FROM列表中包含的子查詢被標記爲DERIVED(衍生)
MySQL會遞歸執行這些子查詢, 把結果放在臨時表裏。
select t1.* from t1 ,(select t2.* from t2 where t2.id = 1 ) s2 where t1.id = s2.id
UNION:若第二個SELECT出如今UNION以後,則被標記爲UNION;
UNION RESULT:從UNION表獲取結果的SELECT
#UNION RESULT ,UNION
EXPLAIN
select * from t1
UNION
select * from t2
顯示這一行的數據是關於哪張表的
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。
System:表只有一行記錄(等於系統表),這是const類型的特列,平時不會出現,這個也能夠忽略不計
Const:表示經過索引一次就找到了
const用於比較primary key或者unique索引。由於只匹配一行數據,因此很快
如將主鍵置於where列表中,MySQL就能將該查詢轉換爲一個常量
惟一性索引掃描,對於每一個索引鍵,表中只有一條記錄與之匹配。常見於主鍵或惟一索引掃描
EXPLAIN
SELECT * from t1,t2 where t1.id = t2.id
非惟一性索引掃描,返回匹配某個單獨值的全部行.
本質上也是一種索引訪問,它返回全部匹配某個單獨值的行,然而,它可能會找到多個符合條件的行,因此他應該屬於查找和掃描的混合體
EXPLAIN
select count(DISTINCT col1) from t1 where col1 = 'ac'
或者
EXPLAIN
select col1 from t1 where col1 = 'ac'
只檢索給定範圍的行,使用一個索引來選擇行。key 列顯示使用了哪一個索引
通常就是在你的where語句中出現了between、<、>、in等的查詢
這種範圍掃描索引掃描比全表掃描要好,由於它只須要開始於索引的某一點,而結束語另外一點,不用掃描所有索引。
EXPLAIN select * from t1 where id BETWEEN 30 and 60
EXPLAIN select * from t1 where id in(1,2)
當查詢的結果全爲索引列的時候,雖然也是所有掃描,可是隻查詢的索引庫,而沒有去查詢
數據。
EXPLAIN
select c2 from testdemo
Full Table Scan,將遍歷全表以找到匹配的行
possible_keys:可能使用的key
Key:實際使用的索引。若是爲NULL,則沒有使用索引
查詢中若使用了覆蓋索引,則該索引和查詢的select字段重疊
EXPLAIN select col1,col2 from t1
其中key和possible_keys均可以出現null的狀況
Key_len表示索引中使用的字節數,可經過該列計算查詢中使用的索引的長度。在不損失精確性的狀況下,長度越短越好
key_len顯示的值爲索引字段的最大可能長度,並不是實際使用長度,即key_len是根據表定義計算而得,不是經過表內檢索出的
l key_len表示索引使用的字節數,
l 根據這個值,就能夠判斷索引使用狀況,特別是在組合索引的時候,判斷全部的索引字段是否都被查詢用到。
l char和varchar跟字符編碼也有密切的聯繫,
l 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
datetime類型在5.6中字段長度是5個字節
datetime類型在5.5中字段長度是8個字節
複合索引有最左前綴的特性,若是複合索引能所有使用上,則是複合索引字段的索引長度之和,這也能夠用來斷定複合索引是否部分使用,仍是所有使用。
顯示索引的哪一列被使用了,若是可能的話,是一個常數。哪些列或常量被用於查找索引列上的值
根據表統計信息及索引選用狀況,大體估算出找到所需的記錄所須要讀取的行數
包含不適合在其餘列中顯示但十分重要的額外信息。
表示相應的select操做中使用了覆蓋索引(Covering Index),避免訪問了表的數據行,效率不錯!
若是同時出現using where,代表索引被用來執行索引鍵值的查找;
若是沒有同時出現using where,代表索引用來讀取數據而非執行查找動做