語法
explain +執行的sql語句;
快速開始
- 查看mysql的狀態,瞭解當前mysql server的版本等信息
mysql> status;
mysql Ver 14.14 Distrib 5.7.25, for linux-glibc2.12 (x86_64) using EditLine wrapper
Connection id: 12364
Current database: him
Current user: root@localhost
SSL: Not in use
Current pager: stdout
Using outfile: ‘’
Using delimiter: ;
Server version: 5.7.25 MySQL Community Server (GPL)
Protocol version: 10
Connection: Localhost via UNIX socket
Server characterset: latin1
Db characterset: latin1
Client characterset: utf8
Conn. characterset: utf8
UNIX socket: /my/mysql/mariadb/mysql.sock
Uptime: 23 days 12 hours 23 min 43 sec
Threads: 11 Questions: 92512 Slow queries: 0 Opens: 359 Flush tables: 1 Open tables: 345 Queries per second avg: 0.045 - 創建表和插入數據
創建表
CREATE TABLEtest
(
name
varchar(10) NOT NULL,
age
int(10) DEFAULT NULL,
address
varchar(20) DEFAULT NULL,
PRIMARY KEY (name
)
)
插入數據報錯
mysql> insert into test values(“zhangsan”,18,“上海”);
ERROR 1366 (HY000): Incorrect string value: ‘\xE4\xB8\x8A\xE6\xB5\xB7’ for column ‘address’ at row 1
字符集不對,沒有指定字符集使用的是latin1
mysql> show create table test;
| test | CREATE TABLEtest
(
name
varchar(10) NOT NULL,
age
int(10) DEFAULT NULL,
address
varchar(20) DEFAULT NULL,
PRIMARY KEY (name
)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 |
修改表的字符集
alter table test convert to character set utf8;
現在就可以插入數據了
mysql> insert into test values(“zhangsan”,18,“上海”); - 執行explain語句
mysql> explain insert into test values(“zhangsan”,18,“上海”);
±—±------------±------±-----------±-----±--------------±-----±--------±-----±-----±---------±------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
±—±------------±------±-----------±-----±--------------±-----±--------±-----±-----±---------±------+
| 1 | INSERT | test | NULL | ALL | NULL | NULL | NULL | NULL | NULL | NULL | NULL |
±—±------------±------±-----------±-----±--------------±-----±--------±-----±-----±---------±------+
這裏驗證了兩個問題,執行計劃是不會被真的執行,除select語句使用,insert語句也可以使用
mysql> explain update test set name = “lisi” where name = “zhangsan”;
±—±------------±------±-----------±------±--------------±--------±--------±------±-----±---------±------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
±—±------------±------±-----------±------±--------------±--------±--------±------±-----±---------±------------+
| 1 | UPDATE | test | NULL | range | PRIMARY | PRIMARY | 32 | const | 1 | 100.00 | Using where |
±—±------------±------±-----------±------±--------------±--------±--------±------±-----±---------±------------+
update語句也可以使用,再次驗證explain不會真的去修改數據庫
mysql> explain select * from test;
±—±------------±------±-----------±-----±--------------±-----±--------±-----±-----±---------±------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
±—±------------±------±-----------±-----±--------------±-----±--------±-----±-----±---------±------+
| 1 | SIMPLE | test | NULL | ALL | NULL | NULL | NULL | NULL | 1 | 100.00 | NULL |
±—±------------±------±-----------±-----±--------------±-----±--------±-----±-----±---------±------+
mysql> explain delete from test;
±—±------------±------±-----------±-----±--------------±-----±--------±-----±-----±---------±------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
±—±------------±------±-----------±-----±--------------±-----±--------±-----±-----±---------±------------------+
| 1 | DELETE | test | NULL | ALL | NULL | NULL | NULL | NULL | 1 | 100.00 | Deleting all rows |
±—±------------±------±-----------±-----±--------------±-----±--------±-----±-----±---------±------------------+
explain 返回字段解釋
- id
id 相同執行順序由上至下
id 不同,id的值越大優先級越高,越先被執行
id 爲NULL時表示一個結果集,常見爲union中
例如下面的例子
mysql> explain select uid from user_qq union select uid from user;
±—±-------------±-----------±-----------±------±--------------±-------------±--------±-----±-----±---------±----------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
±—±-------------±-----------±-----------±------±--------------±-------------±--------±-----±-----±---------±----------------+
| 1 | PRIMARY | user_qq | NULL | index | NULL | uniq_user_id | 9 | NULL | 6 | 100.00 | Using index |
| 2 | UNION | user | NULL | index | NULL | name | 82 | NULL | 11 | 100.00 | Using index |
| NULL | UNION RESULT | <union1,2> | NULL | ALL | NULL | NULL | NULL | NULL | NULL | NULL | Using temporary |
±—±-------------±-----------±-----------±------±--------------±-------------±--------±-----±-----±---------±----------------+ - select_type
由於往往關心的是查詢的效率,而explain也是將select這一大類分成了很多種情況- SIMPLE 簡單查詢(不使用UNION或子查詢)
例如 explain select * from test; - PRIMARY 最外層的SELECT語句
- DEPENDENT SUBQUERY 依賴的子查詢
mysql> explain select u.*, (select q.openid from user_qq q where u.uid = q.uid) from user u;
±—±-------------------±------±-----------±-----±--------------±-------------±--------±----------±-----±---------±------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
±—±-------------------±------±-----------±-----±--------------±-------------±--------±----------±-----±---------±------+
| 1 | PRIMARY | u | NULL | ALL | NULL | NULL | NULL | NULL | 11 | 100.00 | NULL |
| 2 | DEPENDENT SUBQUERY | q | NULL | ref | uniq_user_id | uniq_user_id | 9 | him.u.uid | 1 | 100.00 | NULL |
±—±-------------------±------±-----------±-----±--------------±-------------±--------±----------±-----±---------±------+ - SUBQUERY 子查詢(沒有依賴的子查詢)
explain select u.*, (select q.openid from user_qq q where q.uid =1) from user u; - UNION 聯合查詢,UNION後的查詢
- UNION RESULT 聯合查詢的結果
mysql> explain select uid from user union select uid from user_qq;
±—±-------------±-----------±-----------±------±--------------±-------------±--------±-----±-----±---------±----------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
±—±-------------±-----------±-----------±------±--------------±-------------±--------±-----±-----±---------±----------------+
| 1 | PRIMARY | user | NULL | index | NULL | name | 82 | NULL | 11 | 100.00 | Using index |
| 2 | UNION | user_qq | NULL | index | NULL | uniq_user_id | 9 | NULL | 6 | 100.00 | Using index |
| NULL | UNION RESULT | <union1,2> | NULL | ALL | NULL | NULL | NULL | NULL | NULL | NULL | Using temporary |
±—±-------------±-----------±-----------±------±--------------±-------------±--------±-----±-----±---------±----------------+
- SIMPLE 簡單查詢(不使用UNION或子查詢)
- table 即表的名稱,若有別名的則顯示別名
- partitions 表分區,物理存儲文件可以分幾個文件存儲,一張表分幾個文件來存儲
- type 訪問類型
system > const > eq_ref > ref > range > index > ALL 查詢效率依次降低(實際並非嚴格)
system 數據庫引擎爲MyISAM 且只有一條數據
const 命中主鍵或者唯一索引,且查詢條件爲常量且要命中
eq_ref join查詢中關聯的是主鍵或聯合索引例如explain select * from user left join user_qq on user.uid = user_qq.uid;
ref 與const的區別就是這裏是普通索引,可能出現重複數據
range 在索引字段上使用 > ,in,bettwen 等範圍查詢條件
index select中的字段爲索引字段
all 全表掃描 - possible_keys 可能使用到的索引
- key 使用到的索引
- key_len 索引的長度
- ref 連接匹配條件
- rows 返回估算的結果集數目,並不是一個準確的值。
- filtered 這個字段表示存儲引擎返回的數據在server層過濾後,剩下多少滿足查詢的記錄數量的比例,注意是百分比,不是具體記錄數
- extra 額外信息