MySQL explain 字段解释

  • 准备数据
delimiter //
drop procedure if exists produce_data//
create procedure produce_data()
begin
	declare i int default 0;
	drop table if exists a;
	drop table if exists b;
	drop table if exists c;
	create table a(id int not null,name varchar(32));
	create table b(id int not null,name varchar(32));
	create table c(id int not null,name varchar(32));
	set i = 1;
	while i <= 4 do
		insert into a(id,name) values(i, concat('name', i));
		set i = i + 1;
	end while;
	set i = 3;
	while i <= 6 do
		insert into b(id,name) values(i, concat('name', i));
		set i = i + 1;
	end while;
	set i = 5;
	while i <= 8 do
		insert into c(id,name) values(i, concat('name', i));
		set i = i + 1;
	end while;
end//
call produce_data()//
delimiter ;
mysql> select * from a;
+----+-------+
| id | name  |
+----+-------+
|  1 | name1 |
|  2 | name2 |
|  3 | name3 |
|  4 | name4 |
+----+-------+
mysql> select * from b;
+----+-------+
| id | name  |
+----+-------+
|  3 | name3 |
|  4 | name4 |
|  5 | name5 |
|  6 | name6 |
+----+-------+
mysql> select * from c;
+----+-------+
| id | name  |
+----+-------+
|  5 | name5 |
|  6 | name6 |
|  7 | name7 |
|  8 | name8 |
+----+-------+
  • 初识字段
mysql> explain select * from a;
+----+-------------+-------+------+---------------+------+---------+------+------+-------+
| id | select_type | table | type | possible_keys | key  | key_len | ref  | rows | Extra |
+----+-------------+-------+------+---------------+------+---------+------+------+-------+
|  1 | SIMPLE      | a     | ALL  | NULL          | NULL | NULL    | NULL |    4 |       |
+----+-------------+-------+------+---------------+------+---------+------+------+-------+
  •  id,表示操作表的顺序

id 全部相同

mysql> explain select * from a,b,c
    -> where a.id = b.id and a.id = c.id;
+----+-------------+-------+------+---------------+------+---------+------+------+--------------------------------+
| id | select_type | table | type | possible_keys | key  | key_len | ref  | rows | Extra                          |
+----+-------------+-------+------+---------------+------+---------+------+------+--------------------------------+
|  1 | SIMPLE      | a     | ALL  | NULL          | NULL | NULL    | NULL |    4 |                                |
|  1 | SIMPLE      | b     | ALL  | NULL          | NULL | NULL    | NULL |    4 | Using where; Using join buffer |
|  1 | SIMPLE      | c     | ALL  | NULL          | NULL | NULL    | NULL |    4 | Using where; Using join buffer |
+----+-------------+-------+------+---------------+------+---------+------+------+--------------------------------+

id 相同,顺序由上至下。  即 a -> b -> c

id 全不相同

mysql> explain select * from b
    -> where b.id = (
    -> select id from a
    -> where id = 
    -> (select id from c
    -> where name = 'name99'));
+----+-------------+-------+------+---------------+------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key  | key_len | ref  | rows | Extra       |
+----+-------------+-------+------+---------------+------+---------+------+------+-------------+
|  1 | PRIMARY     | b     | ALL  | NULL          | NULL | NULL    | NULL |    4 | Using where |
|  2 | SUBQUERY    | a     | ALL  | NULL          | NULL | NULL    | NULL |    4 | Using where |
|  3 | SUBQUERY    | c     | ALL  | NULL          | NULL | NULL    | NULL |    4 | Using where |
+----+-------------+-------+------+---------------+------+---------+------+------+-------------+

 

 id 不同,值越大,越先被操作。即 c -> a -> b

 前两种情况同时存在

 

mysql> explain select * from (
    -> select id from b) bb, c
    -> where bb.id = c.id;
+----+-------------+------------+------+---------------+------+---------+------+------+--------------------------------+
| id | select_type | table      | type | possible_keys | key  | key_len | ref  | rows | Extra                          |
+----+-------------+------------+------+---------------+------+---------+------+------+--------------------------------+
|  1 | PRIMARY     |  | ALL  | NULL          | NULL | NULL    | NULL |    4 |                                |
|  1 | PRIMARY     | c          | ALL  | NULL          | NULL | NULL    | NULL |    4 | Using where; Using join buffer |
|  2 | DERIVED     | b          | ALL  | NULL          | NULL | NULL    | NULL |    4 |                                |
+----+-------------+------------+------+---------------+------+---------+------+------+--------------------------------+

b -> derived2 -> c

  • select_type ,查询类型,用来区别普通查询、联合查询、子查询等复杂查询

常见值:SIMPLE、PRIMARY、SUBQUERY、DERIVED、UNION、UNION RESULT

SIMPLE:简单的 select 查询,查询不包含子查询或UNION;

PRIMARY:查询中若包含任何复杂的子部分,最外层查询则被标记为 PRIMARY;

SUBQUERY:在 SELECT 或 WHERE 列表中包含的子查询;

DERIVED:在 FROM 列表中包含的子查询被标记为 DERIVED

UNION:若第二个SELECT出现在UNION之后,则标记为UNION;若UNION包含在FROM子句的子查询种,外层SELECT则是DERIVED;(被 UNION 的 select )

UNION RESULT:从 UNION 表获取结果的SELECT。

  • table,表名。
  • type,显示查询使用了何种类型。

system,表只有一行记录(等于系统表) ,是 const 类型的特例,基本看不到。经过测试,甚至,只有一条记录也并非是 system,但是以下情况可以:

mysql> explain select t.id, t.name from (select * from a where id = 2) t;
+----+-------------+------------+--------+---------------+---------+---------+------+------+-------+
| id | select_type | table      | type   | possible_keys | key     | key_len | ref  | rows | Extra |
+----+-------------+------------+--------+---------------+---------+---------+------+------+-------+
|  1 | PRIMARY     |  | system | NULL          | NULL    | NULL    | NULL |    1 |       |
|  2 | DERIVED     | a          | const  | PRIMARY       | PRIMARY | 4       |      |    1 |       |
+----+-------------+------------+--------+---------------+---------+---------+------+------+-------+

const,表示通过索引一次就找到了,const 用于比较primary key 或 unique 索引。因为只匹配一行数据,所以很快。如果将主键置于where列表中,MySQL 就能将该查询转换为一个常量。

eq_ref,唯一性索引扫描,对于每个索引键,表中只有一条记录与之匹配。常见于主键或唯一索引扫描。

ref,非唯一性索引扫描,返回匹配某个单独值的所有行。

create index idx_name on a(name);
mysql> explain select * from a where name = 'name1';
+----+-------------+-------+------+---------------+----------+---------+-------+------+-------------+
| id | select_type | table | type | possible_keys | key      | key_len | ref   | rows | Extra       |
+----+-------------+-------+------+---------------+----------+---------+-------+------+-------------+
|  1 | SIMPLE      | a     | ref  | idx_name      | idx_name | 35      | const |    1 | Using where |
+----+-------------+-------+------+---------------+----------+---------+-------+------+-------------+

range,只检索给定范围的行,使用一个索引来选择行。key 列会显示使用了哪个索引。

常见于 where 语句使用 between、<、>、in 等查询。

alter table a add primary key(id);
mysql> explain select * from a where id > 2 and id < 5;
+----+-------------+-------+-------+---------------+---------+---------+------+------+-------------+
| id | select_type | table | type  | possible_keys | key     | key_len | ref  | rows | Extra       |
+----+-------------+-------+-------+---------------+---------+---------+------+------+-------------+
|  1 | SIMPLE      | a     | range | PRIMARY       | PRIMARY | 4       | NULL |    1 | Using where |
+----+-------------+-------+-------+---------------+---------+---------+------+------+-------------+

index,index 与 all 尽管都是遍历,但是 index 遍历的是索引树,而且索引文件通常比数据文件小。

mysql> explain select id from a;
+----+-------------+-------+-------+---------------+----------+---------+------+------+-------------+
| id | select_type | table | type  | possible_keys | key      | key_len | ref  | rows | Extra       |
+----+-------------+-------+-------+---------------+----------+---------+------+------+-------------+
|  1 | SIMPLE      | a     | index | NULL          | idx_name | 35      | NULL |    4 | Using index |
+----+-------------+-------+-------+---------------+----------+---------+------+------+-------------+

 all,全表扫描。

你可能感兴趣的:(MySQL explain 字段解释)