程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> MYSQL數據庫 >> MySQL綜合教程 >> MySQL之explain的type列

MySQL之explain的type列

編輯:MySQL綜合教程

explain 可以分析 select 語句的執行,即 MySQL 的“執行計劃。

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 按索引次序掃描表,就是先讀索引,再讀實際的行,其實還是全表掃描。主要優點是避免了排序,因為索引是排好序的。(按照索引的排序去讀對應的數據行。) create table a(a_id int not null, key(a_id)); insert into a value(1),(2); mysql> explain select * 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 了。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved