Mysql-Explain(一):explain簡介和輸出列解釋
Mysql-Explain(一):explain簡介和輸出列解釋
Mysql-Explain(二):explain實驗數據準備
Mysql-Explain(三):輸出列-id
Mysql-Explain(四):輸出列-select_type
Mysql-Explain(五):輸出列-type
Mysql-Explain(六):輸出列-possiable_keys、key、key_len
Mysql-Explain(七):輸出列-ref、rows
Mysql-Explain(八):輸出列-extra
explain簡介
explain和SQL語句一起使用的時候,MySQL將顯示來自優化器的相關語句執行計劃的信息,包括表的讀取順序、數據讀取操作的操作類型、那些索引可以被使用、那些索引會被實際使用、表之間的引用、每張表大概需要讀取多少行記錄等等。通過這些我們能分析SQL語句的結構和性能瓶頸,從而優化我們的SQL語句。
example:
mysql> explain select * from student where id < 10;
+----+-------------+---------+------------+-------+---------------+---------+---------+------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+---------+------------+-------+---------------+---------+---------+------+------+----------+-------------+
| 1 | SIMPLE | student | NULL | range | PRIMARY | PRIMARY | 4 | NULL | 9 | 100.00 | Using where |
+----+-------------+---------+------------+-------+---------------+---------+---------+------+------+----------+-------------+
1 row in set, 1 warning (0.24 sec)
explain輸出列解釋
字段 | 字段說明 | 字段值描述 | |
---|---|---|---|
id | select查詢序列號,包含一組數字,表示查詢中執行select子句或者操作表的順序 | id相同 | 執行順序由上至下 |
id不相同 | 如果是子查詢,id的序號會遞增,id的值越大被執行的優先級越高 | ||
id相同和不相同都存在 | 如果id相同可以認爲是一組,同一組id執行順序由上至下,不同組之間,id值越大被執行的優先級越高 | ||
select_type | 查詢的類型,主要用來區別普通查詢,聯合查詢,子查詢等複雜查詢 | SIMPLE | 簡單的select查詢,查詢中不包含子查詢或者UNION |
PRIMARY | 查詢中若包含任何複雜的子部分,最外層的查詢則被標記爲PRIMARY | ||
SUBQUERY | 在select或者where列表中包含了子查詢 | ||
DERIVED | 在from列表中包含的子查詢會被標記爲DERICED(衍生),Mysql會遞歸地執行這些子查詢,然後把結果放到臨時表 | ||
UNION | 若第二個select語句出現在UNION之後,則被標記爲UNION。若UNION包含在from子句的子查詢中,外層select則被標記爲DERIVED | ||
UNION RESULT | 從union表獲取結果的select | ||
type | 訪問類型排序,顯示查詢使用了何種類型,從最好到最差依次是:system>const>eq_ref>ref>range>index>ALL | system | 表只有一行記錄,這是const類型的特例,這個平時很少出現 |
const | 表最多有一個匹配行,它將在查詢開始時被讀取。因爲僅有一行記錄匹配,所以這行的列值可被優化器剩餘部分認爲是常數。const表很快,因爲它們只讀取一次! | ||
eq_ref | 驅動表和關聯表中的每行進行組合並且僅有一行記錄。這是除了system 和 const 類型之外, 這是最好的聯接類型。當連接使用索引的所有部分時, 索引是主鍵或唯一非 NULL 索引時, 將使用該值 | ||
ref | 非唯一性索引掃描,返回符合某個索引值的所有記錄,可能會有多條記錄匹配 | ||
range | 使用一個索引來檢索給定範圍的行,這種範圍索引掃描比全表掃描效率要高 | ||
index | 使用覆蓋索引 | ||
all | 全表掃描(full table scan) | ||
possiable_keys | 顯示可能應用在這張表中的索引,一個或者多個,查詢的涉及的字段若存在索引,則該索引被列出,但是不一定被查詢實際用到 | ||
key | 實際使用的索引,如果爲NULL,則沒有使用索引;若查詢中使用了覆蓋索引,則該索引只會出現在key列表中 | ||
key_len | 表示索引中使用的字節數,可通過該列計算查詢中所使用索引的長度,在損失精度的情況下,索引長度越短越好;key_len顯示的值爲索引字段最大的可能長度,並非實際使用的長度,即key_len是根據表的定義計算而得,並非通過表內檢索出的 | ||
ref | 哪些列或者常量被用做索引列上的值 | ||
rows | 根據表的統計信息和索引的使用情況,大致估算查詢結果所需要讀取記錄的行數 | ||
extra | 包含其explain字段不適合顯示但又十分重要的額外信息 | using filesort | 使用文件內排序 |
using tmporary | 使用臨時表保存中間結果,常見於排序order by和分組group by | ||
Using index | 表示覆蓋索引即可滿足查詢要求,因而無需再回表查詢 | ||
Using index for group by | 讀取和分組都使用了覆蓋索引 | ||
Using where | Server層對存儲引擎層返回的數據做where條件過濾 | ||
impossiable where | where的值總fasle,不能獲取任何記錄 | ||
Using join buffer | 聯表查詢時使用的緩存策略,有Block Nested-Loop Join和Batched Key Access兩種策略 | ||
Select tables optimized away | 在沒有group by子句的情況下,基於索引優化的MAX/MIN操作,或者基於MyISAM存儲引擎優化的COUNT(*)操作,不必等到執行階段再進行計算,在查詢計劃生成階段既可以完成優化 | ||
Distinct | 優化Distinct操作,在找到匹配的第一行記錄後,立馬停止查找同樣的值 |