mysql explain insert_MySQL之EXPLAIN 执行计划详解
explain 可以分析 select語句的執(zhí)行,即 MySQL 的“執(zhí)行計(jì)劃。
一、type 列
MySQL 在表里找到所需行的方式。包括(由左至右,由最差到最好):| All | index | range | ref | eq_ref | const,system | null |
ALL(所有)
全表掃描,MySQL 從頭到尾掃描整張表查找行。
mysql> explain select * froma\G
...
type:ALL如果加上 limit 如select * from a limit 100 MySQL 會掃描 100行,但掃描方式不會變,還是從頭到尾掃描。index(索引)
根據(jù)索引來讀取數(shù)據(jù),如果索引已包含了查詢數(shù)據(jù),只需掃描索引樹,否則執(zhí)行全表掃描和All類似;create table a(a_id int not null, key(a_id));insert into a value(1),(2);
mysql> explain select a_id froma\G
...
type:indexrange(范圍)
以范圍的形式掃描索引
建表: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(等值引用)
使用有唯一性索引查找(主鍵或唯一性索引)
建表及插入數(shù)據(jù):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 joina_info using(id);
...+--------+--------+...
...| table | type |...
...+--------+--------+...
...| a | index |...
...| a_info | eq_ref |...
...+--------+--------+...
此時(shí) a_info 每條記錄與 a 一一對應(yīng),通過主鍵 id 關(guān)聯(lián)起來,所以 a_info 的 type 為 eq_ref。
刪除 a_info 的主鍵:ALTER TABLE `a_info` DROP PRIMARY KEY;
現(xiàn)在 a_info 已經(jīng)沒有索引了:
mysql> explain select * from a joina_info using(id);+----+...+--------+--------+...
| id |...| table | type |...+----+...+--------+--------+...
| 1 |...| a_info | ALL |...| 1 |...| a | eq_ref |...+----+...+--------+--------+...
這次 MySQL 調(diào)整了執(zhí)行順序,先全表掃描 a_info 表,再對表 a 進(jìn)行 eq_ref 查找,因?yàn)?a 表 id 還是主鍵。
刪除 a 的主鍵:alter table a drop primary key;
現(xiàn)在 a 也沒有索引了:
mysql> explain select * from a joina_info using(id);
...+--------+------+...
...| table | type |...
...+--------+------+...
...| a | ALL |...
...| a_info | ALL |...
...+--------+------+...
現(xiàn)在兩個(gè)表都使用全表掃描了。
建表及插入數(shù)據(jù):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');
現(xiàn)在 a_info 表 id 列變?yōu)槠胀ㄋ饕?非唯一性索引):
mysql> explain select * from a join a_info using(id) where a.id=1;
...+--------+-------+...
...| table | type |...
...+--------+-------+...
...| a | const |...
...| a_info | ref |...
...+--------+-------+...
a_info 表 type 變?yōu)?ref 類型了。
所以,唯一性索引才會出現(xiàn) eq_ref (非唯一性索引會出現(xiàn) ref ),因?yàn)槲ㄒ?#xff0c;所以最多只返回一條記錄,找到后無需繼續(xù)查找,因此比 ref 更快。
const(常量連接)
被稱為“常量”,這個(gè)詞不好理解,不過出現(xiàn) const 的話就表示發(fā)生下面兩種情況:
在整個(gè)查詢過程中這個(gè)表最多只會有一條匹配的行,比如主鍵 id=1 就肯定只有一行,只需讀取一次表數(shù)據(jù)便能取得所需的結(jié)果,且表數(shù)據(jù)在分解執(zhí)行計(jì)劃時(shí)讀取。返回值直接放在 select 語句中,類似 select 1 ASf 。可以通過 extended 選擇查看內(nèi)部過程:
建表及插入數(shù)據(jù):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 是如何優(yōu)化的:
mysql>show warnings\G
...
Message:select '1' AS `id`,'asdfasdf' AS `c1`,'asdfasdf' AS `c2`,'asdfasdf' AS`c3`from `test`.`a` where 1查詢返回的結(jié)果為:
mysql> select * from a where id=1;+----+----------+----------+----------+
| id | c1 | c2 | c3 |
+----+----------+----------+----------+
| 1 | asdfasdf | asdfasdf | asdfasdf |
+----+----------+----------+----------+
可以看出,返回結(jié)果中的字段值都以“值 AS 字段名”的形式直接出現(xiàn)在優(yōu)化后的 select語句中。
修改一下查詢:
mysql> explain select * from a where id in(1,2)\G
...
type: range
...
當(dāng)返回結(jié)果超過1條時(shí), type 便不再為 const 了。
重新建表及插入數(shù)據(jù):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,因?yàn)橹挥形ㄒ恍运饕拍鼙WC表中最多只有一條記錄,只有這樣 type 才有可能為 const 。
為 id 加普通索引后, type 變?yōu)?ref ,改為加唯一或主鍵索引后, type 便變?yōu)?const 了。
二、Extra 列
Extra表示附加信息,常見的有如下幾種(也按查詢效率從高到低排列):
Usingindex:表示使用索引,如果只有 Using index,說明他沒有查詢到數(shù)據(jù)表,只用索引表就完成了這個(gè)查詢,這個(gè)叫覆蓋索引。如果同時(shí)出現(xiàn)Using where,代表使用索引來查找讀取記錄, 也是可以用到索引的,但是需要查詢到數(shù)據(jù)表。
Usingwhere:表示條件查詢,如果不讀取表的所有數(shù)據(jù),或不是僅僅通過索引就可以獲取所有需要的數(shù)據(jù),則會出現(xiàn) Using where。如果type列是ALL或index,而沒有出現(xiàn)該信息,則你有可能在執(zhí)行錯誤的查詢:返回所有數(shù)據(jù)。
Using filesort:不是“使用文件索引”的含義!filesort是MySQL所實(shí)現(xiàn)的一種排序策略,通常在使用到排序語句ORDER BY的時(shí)候,會出現(xiàn)該信息。
Usingtemporary:表示為了得到結(jié)果,使用了臨時(shí)表,這通常是出現(xiàn)在多表聯(lián)合查詢,結(jié)果排序的場合。
如果EXPLAIN出現(xiàn)后面兩個(gè)信息(Using filesort,Usingtemporary),而rows又比較大,通常意味著你需要調(diào)整查詢語句,或者需要添加索引,總之需要盡量消除這兩個(gè)信息。
轉(zhuǎn)自:http://blog.csdn.net/xtdhqdhq/article/details/20377273
總結(jié)
以上是生活随笔為你收集整理的mysql explain insert_MySQL之EXPLAIN 执行计划详解的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 装win10bios怎么调 Win10怎
- 下一篇: xp磁盘有写保护怎么格式化 解决XP磁盘