explain 能夠分析 select 語句的執行,即 MySQL 的「執行計劃。 1、type 列 MySQL 在表裏找到所需行的方式。包括(由左至右,由最差到最好): | All | index | range | ref | eq_ref | const,system | null | ALL(全部) 全表掃描,MySQL 從頭至尾掃描整張表查找行。 mysql> explain select * from a\G ... type: ALL 若是加上 limit 如 select * from a limit 100 MySQL 會掃描 100 行,但掃描方式不會變,仍是從頭至尾掃描。 index(索引) 根據索引來讀取數據,若是索引已包含了查詢數據,只需掃描索引樹,不然執行全表掃描和All相似; create table a(a_id int not null, key(a_id)); insert into a value(1),(2); mysql> explain select a_id from a\G ... type: index range(範圍) 以範圍的形式掃描索引 建表: create table a(a_id int not null, key(a_id)); insert into a values(1),(2),(3),(4),(5),(6),(7),(8),(9),(10); mysql> explain select * from a where a_id > 1\G ... type: range ... IN 比較符也會用 range 表示: mysql> explain select * from a where a_id in (1,3,4)\G ... type: range ... ` ref(引用) 非惟一性索引訪問 建表: create table a(a_id int not null, key(a_id)); insert into a values(1),(2),(3),(4),(5),(6),(7),(8),(9),(10); mysql> explain select * from a where a_id=1\G ... type: ref ... eq_ref(等值引用) 使用有惟一性索引查找(主鍵或惟一性索引) 建表及插入數據: create table a(id int primary key); create table a_info(id int primary key, title char(1)); insert into a value(1),(2); insert into a_info value(1, 'a'),(2, 'b'); mysql> explain select * from a join a_info using(id); ...+--------+--------+... ...| table | type |... ...+--------+--------+... ...| a | index |... ...| a_info | eq_ref |... ...+--------+--------+... 此時 a_info 每條記錄與 a 一一對應,經過主鍵 id 關聯起來,因此 a_info 的 type 爲 eq_ref。 刪除 a_info 的主鍵:ALTER TABLE `a_info` DROP PRIMARY KEY; 如今 a_info 已經沒有索引了: mysql> explain select * from a join a_info using(id); +----+...+--------+--------+... | id |...| table | type |... +----+...+--------+--------+... | 1 |...| a_info | ALL |... | 1 |...| a | eq_ref |... +----+...+--------+--------+... 此次 MySQL 調整了執行順序,先全表掃描 a_info 表,再對錶 a 進行 eq_ref 查找,由於 a 表 id 仍是主鍵。 刪除 a 的主鍵:alter table a drop primary key; 如今 a 也沒有索引了: mysql> explain select * from a join a_info using(id); ...+--------+------+... ...| table | type |... ...+--------+------+... ...| a | ALL |... ...| a_info | ALL |... ...+--------+------+... 如今兩個表都使用全表掃描了。 建表及插入數據: create table a(id int primary key); create table a_info(id int, title char(1), key(id)); insert into a value(1),(2); insert into a_info value(1, 'a'),(2, 'b'); 如今 a_info 表 id 列變爲普通索引(非惟一性索引): mysql> explain select * from a join a_info using(id) where a.id=1; ...+--------+-------+... ...| table | type |... ...+--------+-------+... ...| a | const |... ...| a_info | ref |... ...+--------+-------+... a_info 表 type 變爲 ref 類型了。 因此,惟一性索引纔會出現 eq_ref (非惟一性索引會出現 ref ),由於惟一,因此最多隻返回一條記錄,找到後無需繼續查找,所以比 ref 更快。 const(常量鏈接) 被稱爲「常量」,這個詞很差理解,不過出現 const 的話就表示發生下面兩種狀況: 在整個查詢過程當中這個表最多隻會有一條匹配的行,好比主鍵 id=1 就確定只有一行,只需讀取一次表數據便能取得所需的結果,且表數據在分解執行計劃時讀取。返回值直接放在 select 語句中,相似 select 1 AS f 。能夠經過 extended 選擇查看內部過程: 建表及插入數據: create table a(id int primary key, c1 char(20) not null, c2 text not null, c3 text not null); insert into a values(1, 'asdfasdf', 'asdfasdf', 'asdfasdf'), (2, 'asdfasdf', 'asdfasdf', 'asdfasdf'); mysql> explain extended select * from a where id=1\G ... type: const possible_keys: PRIMARY key: PRIMARY ... 用 show warnings 查看 MySQL 是如何優化的: mysql> show warnings\G ... Message: select '1' AS `id`,'asdfasdf' AS `c1`,'asdfasdf' AS `c2`,'asdfasdf' AS `c3` from `test`.`a` where 1 查詢返回的結果爲: mysql> select * from a where id=1; +----+----------+----------+----------+ | id | c1 | c2 | c3 | +----+----------+----------+----------+ | 1 | asdfasdf | asdfasdf | asdfasdf | +----+----------+----------+----------+ 能夠看出,返回結果中的字段值都以「值 AS 字段名」的形式直接出如今優化後的 select 語句中。 修改一下查詢: mysql> explain select * from a where id in(1,2)\G ... type: range ... 當返回結果超過 1 條時, type 便再也不爲 const 了。 從新建表及插入數據: create table a (id int not null); insert into a value(1),(2),(3); mysql> explain select * from a where id=1\G ... type: ALL 目前表中只有一條 id=1 的記錄,但 type 已爲 ALL ,由於只有惟一性索引才能保證表中最多隻有一條記錄,只有這樣 type 纔有可能爲 const 。 爲 id 加普通索引後, type 變爲 ref ,改成加惟一或主鍵索引後, type 便變爲 const 了。 2、Extra 列 Extra表示附加信息,常見的有以下幾種(也按查詢效率從高到低排列): Using index:表示使用索引,若是隻有 Using index,說明他沒有查詢到數據表,只用索引表就完成了這個查詢,這個叫覆蓋索引。若是同時出現Using where,表明使用索引來查找讀取記錄, 也是能夠用到索引的,可是須要查詢到數據表。 Using where:表示條件查詢,若是不讀取表的全部數據,或不是僅僅經過索引就能夠獲取全部須要的數據,則會出現 Using where。若是type列是ALL或index,而沒有出現該信息,則你有可能在執行錯誤的查詢:返回全部數據。 Using filesort:不是「使用文件索引」的含義!filesort是MySQL所實現的一種排序策略,一般在使用到排序語句ORDER BY的時候,會出現該信息。 Using temporary:表示爲了獲得結果,使用了臨時表,這一般是出如今多表聯合查詢,結果排序的場合。 若是EXPLAIN出現後面兩個信息(Using filesort,Using temporary),而rows又比較大,一般意味着你須要調整查詢語句,或者須要添加索引,總之須要儘可能消除這兩個信息。 轉自:http://blog.csdn.net/xtdhqdhq/article/details/20377273