使用EXPLAIN关键字可以模拟优化器执行SQL语句,分析查询语句或是结构的性能瓶颈。在select语句之前增加explaion关键字,MySQL会在查询上设置一个标记,执行查询会返回执行计划的信息,而不是执行SQL。
Explaion分析示例 -- actor建表语句: CREATE TABLE `actor` ( `id` int(11) NOT NULL, `name` varchar(45) DEFAULT NULL, `update_time` datetime DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 -- film建表语句: CREATE TABLE `film` ( `id` int(11) NOT NULL, `name` varchar(10) NOT NULL, PRIMARY KEY (`id`), KEY `idx_name` (`name`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 -- film_actor建表语句: CREATE TABLE `film_actor` ( `id` int(11) NOT NULL, `film_id` int(11) NOT NULL, `actor_id` int(11) NOT NULL, `remark` varchar(255) DEFAULT NULL, PRIMARY KEY (`id`), KEY `idx_film_actor_id` (`film_id`,`actor_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8执行explain:
explain select * from actor;如果是select语句返回的是执行结果,在select语句前面加上explain返回的是这条查询语句的执行SQL。
EXPLAIN两个变种 explain extended会在explain的基础上额外提供一些查询优化的信息。紧随其后通过show warnings命令可以得到优化后的查询语句,从而看出优化器优化了什么。额外还有filtered列,是一个半分比的值,rows*filtered / 100可以估算出将要和explain中前一个表进行连接的行数(前一个表指explain中的id值比当前表id值小的表)。
explain EXTENDED select * from actor where id = 1; explain partitions相比explain多了个partitions字段,如果查询是基于分区表的话,会显示查询将访问的分区。
Explain中的列 id列id列的编号是select的序列号,有几个select就有几个id,并且id的顺序是按select出现的顺序增长的。
id越大执行优先级越高,id相同则从上往下执行,id为NULL最后执行。
select type表示对应行是简单还是复杂的查询。
simple:简单查询。查询不包含子查询和union。
primary:复杂查询中最外层的select
subquery:包含在select中的子查询(不在from子句中)
derived:包含在from子句中的子查询。MySQL会将结果存放在一个临时表中,也称为派生表。
union:在union关键字随后的selelct。
EXPLAIN select 1 union all select 1; table列