每日MySQL之020:使用EXPLAIN查看SQL的执行计划
2017-08-13 20:37
816 查看
MySQL中要查看执行计划,可以使用EXPLAIN命令,EXPLAIN 使用的对象是 SELECT, DELETE, INSERT, REPLACE, 和 UPDATE 语句。将EXPLAIN换成DESCRIBE也行,两者含义一样,但实际操作中一般用DESCRIBE查看表结构,用EXPLAIN查看执行计划。输出的结果不是图形化的,而是一张表。对于每个SELECT语句中的每个表,EXPLAIN都会返回一行。返回的顺序就是MySQL读取表的顺序。MySQL使用nested-loop join来完成所有的join工作。
先来看两个简单的例子,第一个SELECT语句访问一张表,只有一行输出。第二个SELECT语句访问两张表,就有两行输出,table列指定了访问的表名:
再详细看一下各个字段的含义,假设我们有以下三张表:
id (JSON name: select_id)
SELECT ID, 查询语句中SELECT的编号。如果是union的结果,可能为空值,这时table column显示的是<unionM,N>。
示例1: 第一个语句有两个SELECT语句,所以有两个id,第二个语句有三个SELECT,所以有三个id,UNION RESULT的id为空:
select_type (JSON name: none)
SIMPLE:简单查询(不使用UNION或者子查询)
PRIMARY: 最外边SELECT
UNION: UNION中第二个及以后的SELECT
参考示例1。
table (JSON name: table_name)
表名。
partitions (JSON name: partitions)
分区表的分区名,对于非分区表,为NULL
type (JSON name: access_type)
Join type,可以参考:链接http://blog.csdn.net/qingsong3333/article/details/77149845
possible_keys (JSON name: possible_keys)
可能选择的索引
key (JSON name: key)
最终选择的索引
示例2,第一条SELECT没有使用索引, 第二条使用了索引idx1,第三条使用了PRIMARY KEY。
key_len (JSON name: key_length)
key的长度
rows (JSON name: rows)
MySQL认为完成查询需要访问的行数,只是个估计值。
filtered (JSON name: filtered)
被条件过滤掉的百分比。That is, rows shows the estimated number of rows examined and rows × filtered / 100
shows the number of rows that will be joined with previous tables.
Extra (JSON name: none)
额外说明
另外,可以设置 FORMAT 参数,如果设为JSON,则显示为JSON格式:
先来看两个简单的例子,第一个SELECT语句访问一张表,只有一行输出。第二个SELECT语句访问两张表,就有两行输出,table列指定了访问的表名:
mysql> EXPLAIN SELECT id, age from t1; +----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------+ | 1 | SIMPLE | t1 | NULL | ALL | NULL | NULL | NULL | NULL | 6 | 100.00 | NULL | +----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------+ 1 row in set, 1 warning (0.00 sec) mysql> EXPLAIN SELECT t1.id, t1.age, t2.name FROM t1,t2; +----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+---------------------------------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+---------------------------------------+ | 1 | SIMPLE | t2 | NULL | ALL | NULL | NULL | NULL | NULL | 4 | 100.00 | NULL | | 1 | SIMPLE | t1 | NULL | ALL | NULL | NULL | NULL | NULL | 6 | 100.00 | Using join buffer (Block Nested Loop) | +----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+---------------------------------------+ 2 rows in set, 1 warning (0.01 sec)
再详细看一下各个字段的含义,假设我们有以下三张表:
mysql> CREATE TABLE `t1` (id int, age int, KEY `idx1` (`id`)); mysql> CREATE TABLE `t2` ( `id` int(11),`name` char(15)); mysql> CREATE TABLE `t3` (id int not null primary key, name char(30)); mysql> INSERT INTO `t1` VALUES (1001,24),(1002,25),(1003,43),(1004,44),(1006,31),(1005,23); mysql> INSERT INTO `t2` VALUES (1002,'name1'),(1005,'name2'),(1007,'name3'),(1010,'name4'); mysql> INSERT INTO `t3` VALUES (10086, 'Mobile'),(10011, 'Unicom'),(95583,'CommercialBank'),(12355,'taxiBue'),(1010,'aa'); mysql> ANALYZE TABLE t1; mysql> ANALYZE TABLE t2; mysql> ANALYZE TABLE t3; mysql> select * from t1; +------+------+ | id | age | +------+------+ | 1001 | 24 | | 1002 | 25 | | 1003 | 43 | | 1004 | 44 | | 1006 | 31 | | 1005 | 23 | +------+------+ 6 rows in set (0.01 sec) mysql> select * from t2; +------+-------+ | id | name | +------+-------+ | 1002 | name1 | | 1005 | name2 | | 1007 | name3 | | 1010 | name4 | +------+-------+ 4 rows in set (0.00 sec) mysql> select * from t3; +-------+----------------+ | id | name | +-------+----------------+ | 1010 | aa | | 10011 | Unicom | | 10086 | Mobile | | 12355 | taxiBue | | 95583 | CommercialBank | +-------+----------------+ 5 rows in set (0.00 sec)
id (JSON name: select_id)
SELECT ID, 查询语句中SELECT的编号。如果是union的结果,可能为空值,这时table column显示的是<unionM,N>。
示例1: 第一个语句有两个SELECT语句,所以有两个id,第二个语句有三个SELECT,所以有三个id,UNION RESULT的id为空:
mysql> EXPLAIN SELECT * FROM t1 UNION SELECT * FROM t2; +----+--------------+------------+ | id | select_type | table | +----+--------------+------------+ | 1 | PRIMARY | t1 | | 2 | UNION | t2 | |NULL| UNION RESULT | <union1,2> | +----+--------------+------------+ 3 rows in set, 1 warning (0.00 sec) mysql> EXPLAIN SELECT * FROM t1 UNION SELECT * FROM t2 UNION SELECT * FROM t3; +----+--------------+--------------+ | id | select_type | table | +----+--------------+--------------+ | 1 | PRIMARY | t1 | | 2 | UNION | t2 | | 3 | UNION | t3 | |NULL| UNION RESULT | <union1,2,3> | +----+--------------+--------------+ 4 rows in set, 1 warning (0.00 sec)
select_type (JSON name: none)
SIMPLE:简单查询(不使用UNION或者子查询)
PRIMARY: 最外边SELECT
UNION: UNION中第二个及以后的SELECT
参考示例1。
table (JSON name: table_name)
表名。
partitions (JSON name: partitions)
分区表的分区名,对于非分区表,为NULL
type (JSON name: access_type)
Join type,可以参考:链接http://blog.csdn.net/qingsong3333/article/details/77149845
possible_keys (JSON name: possible_keys)
可能选择的索引
key (JSON name: key)
最终选择的索引
示例2,第一条SELECT没有使用索引, 第二条使用了索引idx1,第三条使用了PRIMARY KEY。
mysql> EXPLAIN SELECT * FROM t1 where id < 1005; +----+-------------+-------+...+---------------+------+---------+------+------+----------+-------------+ | id | select_type | table |...| possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+-------+...+---------------+------+---------+------+------+----------+-------------+ | 1 | SIMPLE | t1 |...| idx1 | NULL | NULL | NULL | 6 | 66.67 | Using where | +----+-------------+-------+...+---------------+------+---------+------+------+----------+-------------+ mysql> EXPLAIN SELECT * FROM t1 where id > 1004; +----+-------------+-------+...+---------------+------+---------+------+------+----------+-----------------------+ | id | select_type | table |...| possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+-------+...+---------------+------+---------+------+------+----------+-----------------------+ | 1 | SIMPLE | t1 |...| idx1 | idx1 | 5 | NULL | 2 | 100.00 | Using index condition | +----+-------------+-------+...+---------------+------+---------+------+------+----------+-----------------------+ mysql> EXPLAIN SELECT * FROM t3 where id > 10010; +----+-------------+-------+...+---------------+---------+---------+------+------+----------+-------------+ | id | select_type | table |...| possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+-------+...+---------------+---------+---------+------+------+----------+-------------+ | 1 | SIMPLE | t3 |...| PRIMARY | PRIMARY | 4 | NULL | 4 | 100.00 | Using where | +----+-------------+-------+...+---------------+---------+---------+------+------+----------+-------------+
key_len (JSON name: key_length)
key的长度
rows (JSON name: rows)
MySQL认为完成查询需要访问的行数,只是个估计值。
filtered (JSON name: filtered)
被条件过滤掉的百分比。That is, rows shows the estimated number of rows examined and rows × filtered / 100
shows the number of rows that will be joined with previous tables.
Extra (JSON name: none)
额外说明
另外,可以设置 FORMAT 参数,如果设为JSON,则显示为JSON格式:
mysql> EXPLAIN FORMAT=JSON SELECT id, age from t1 \G *************************** 1. row *************************** EXPLAIN: { "query_block": { "select_id": 1, "cost_info": { "query_cost": "2.20" }, "table": { "table_name": "t1", "access_type": "ALL", "rows_examined_per_scan": 6, "rows_produced_per_join": 6, "filtered": "100.00", "cost_info": { "read_cost": "1.00", "eval_cost": "1.20", "prefix_cost": "2.20", "data_read_per_join": "96" }, "used_columns": [ "id", "age" ] } } } 1 row in set, 1 warning (0.00 sec)
相关文章推荐
- MySQL使用explain查看执行计划
- MySQL 使用 explain 查看SQL语句执行效率
- MySQL中使用explain和profile分析SQL执行计划和性能
- 在MySQL中使用explain查询SQL的执行计划
- MySql中如何使用 explain 查询 SQL 的执行计划
- MySQL 使用explain查看执行计划
- Mysql查看执行计划-explain
- hive高阶1--sql和hive语句执行顺序、explain查看执行计划、group by生成MR
- mysql的SQL语句执行计划分析:EXPLAIN
- 启用sqlplus的explain功能,保存结果至文件,查看sql的执行计划
- Mysql SQL Explain执行计划
- mysql中explain查看sql语句执行效率
- TOAD中查看SQL的执行计划(Explain Plan)
- 问题3:mysql explain执行计划查看
- Mysql利用profiles来查看sql 语句执行计划
- MYSQL查看执行计划 Explain
- MySql使用show processlist查看正在执行的Sql语句
- 使用mysql profiles 来查看sql 语句执行计划
- Mysql之执行计划 查看索引利用情况 explain
- Mysql之执行计划 查看索引利用情况 explain