MySQL 执行计划详解

(admin@g1-db-test-v07:5001)[jinhailan]>explain select * 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 |    3 |   100.00 | NULL  |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------+

explain输出

 id:在一个大的查询语句中每个SELECT关键字都对应一个唯一的id

select_type:SELECT关键字对应的那个查询的类型

table:表名

partitions:匹配的分区信息

type:针对单表的访问方法

possible_keys:可能用到的索引

key:实际使用的索引

key_len:实际使用到的索引长度

ref:当使用索引列等值查询时,与索引列进行等值匹配的对象信息

rows:预估的需要读取的记录条数

filtered:某个表经过搜索条件过滤后剩余记录条数的百分比

Extra:一些额外的信息

执行计划输出详解

table

 

不论我们的查询语句有多复杂,里边儿包含了多少个表,到最后也是需要对每个表进行单表访问的,EXPLAIN语句输出的每条记录都对应着某个单表的访问方法,该条记录的table列代表着该表的表名

 

id

查询语句中每出现一个SELECT关键字,设计MySQL的大叔就会为它分配一个唯一的id

对于连接查询来说,一个SELECT关键字后边的FROM子句中可以跟随多个表,所以在连接查询的执行计划中,每个表都会对应一条记录,但是这些记录的id值都是相同的

(admin@g1-db-test-v07:5001)[jinhailan]>EXPLAIN SELECT * FROM t1 INNER JOIN t2;
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+---------------------------------------+
| id | select_type | table | partitions | type | possible_keys | key  | key_len | ref  | rows | filtered | Extra                                 |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+---------------------------------------+
|  1 | SIMPLE      | t1    | NULL       | ALL  | NULL          | NULL | NULL    | NULL |    3 |   100.00 | NULL                                  |
|  1 | SIMPLE      | t2    | NULL       | ALL  | NULL          | NULL | NULL    | NULL |    3 |   100.00 | Using join buffer (Block Nested Loop) |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+---------------------------------------+
2 rows in set, 1 warning (0.00 sec)

  在连接查询的执行计划中,每个表都会对应一条记录,这些记录的id列的值是相同的,出现在前边的表表示驱动表,出现在后边的表表示被驱动表

查询优化器可能对涉及子查询的查询语句进行重写,从而转换为连接查询

 

Extra

 

Using filesort:

很多情况下排序操作无法使用到索引,只能在内存中(记录较少的时候)或者磁盘中(记录较多的时候)进行排序,设计MySQL的大叔把这种在内存中或者磁盘上进行排序的方式统称为文件排序(英文名:filesort

Using temporary:去重,排序.

执行许多包含DISTINCTGROUP BYUNION等子句的查询过程中,如果不能有效利用索引来完成查询,MySQL很有可能寻求通过建立内部的临时表来执行查询

MySQL会在包含GROUP BY子句的查询中默认添加上ORDER BY子句

不想为包含GROUP BY子句的查询进行排序,需要我们显式的写上ORDER BY NULL

 

Start temporary, End temporary:先看一下自查询优化部分

LooseScan:在将In子查询转为semi-join时,如果采用的是LooseScan执行策略,则在驱动表执行计划的Extra列就是显示LooseScan提示

FirstMatch(tbl_name):在将In子查询转为semi-join时,如果采用的是FirstMatch执行策略,则在被驱动表执行计划的Extra列就是显示FirstMatch(tbl_name)提示

 

posted @ 2020-02-28 09:55  asea金海兰  阅读(258)  评论(0编辑  收藏  举报