MySQL EXPLAIN输出列的详细解释

1. 简介

EXPLAIN语句提供有关 MySQL 如何执行语句的信息。

EXPLAIN与SELECT、DELETE、INSERT、REPLACE和UPDATE语句一起使用。

mysql> EXPLAIN SELECT * FROM employees WHERE emp_no = 10001;
+----+-------------+-----------+------------+-------+---------------+---------+---------+-------+------+----------+-------+
| id | select_type | table     | partitions | type  | possible_keys | key     | key_len | ref   | rows | filtered | Extra |
+----+-------------+-----------+------------+-------+---------------+---------+---------+-------+------+----------+-------+
|  1 | SIMPLE      | employees | NULL       | const | PRIMARY       | PRIMARY | 4       | const |    1 |   100.00 | NULL  |
+----+-------------+-----------+------------+-------+---------------+---------+---------+-------+------+----------+-------+
1 row in set, 1 warning (0.00 sec)

简单来讲,通过EXPLAIN可以分析出SQL语句走没走索引,走的是什么索引。

EXPLAIN为SELECT语句中使用的每个表返回一行信息,它按照 MySQL 在处理语句时读取它们的顺序列出了输出中的表。

MySQL 使用嵌套循环连接(Nested-Loop Join Algorithms)解析所有连接,这意味着 MySQL 从第一个表中读取一行,然后在第二个表,第三个表中找到匹配的行,依此类推。处理完所有表后,MySQL将通过表列表输出选定的列后回溯直到找到一个表,其中存在更多匹配的行。从该表中读取下一行,然后继续下一个表。

2.EXPLAIN 输出列

  • MySQL版本 5.7.33
  • Windows10 64位

从上图看到 EXPLAIN 的结果中,包括的表头id、select_type、table、partitions、type、possible_keys、key、key_len、ref、rows、filtered、Extra,这些字段的意思我们来学习然后通过实例进行了解一下。

2.1 id

SELECT 标识符,查询中 SELECT 的顺序号。如果该行引用其他行的并集结果,则该值可以为NULL。在这种情况下,表列显示类似<unionM,N>的值,以指示该行引用 id 值为 M 和 N 的行的并集。

id 值分三种情况:

id 相同,执行顺序由上至下

mysql> EXPLAIN (
    -> SELECT * FROM employees emp
    -> LEFT JOIN dept_emp de ON emp.emp_no = de.emp_no
    -> LEFT JOIN departments dept ON dept.dept_no = de.dept_no
    -> WHERE emp.emp_no = 10001);
+----+-------------+-------+------------+--------+---------------+---------+---------+----------------------+------+----------+-------+
| id | select_type | table | partitions | type   | possible_keys | key     | key_len | ref                  | rows | filtered | Extra |
+----+-------------+-------+------------+--------+---------------+---------+---------+----------------------+------+----------+-------+
|  1 | SIMPLE      | emp   | NULL       | const  | PRIMARY       | PRIMARY | 4       | const                |    1 |   100.00 | NULL  |
|  1 | SIMPLE      | de    | NULL       | ref    | PRIMARY       | PRIMARY | 4       | const                |    1 |   100.00 | NULL  |
|  1 | SIMPLE      | dept  | NULL       | eq_ref | PRIMARY       | PRIMARY | 12      | employees.de.dept_no |    1 |   100.00 | NULL  |
+----+-------------+-------+------------+--------+---------------+---------+---------+----------------------+------+----------+-------+
3 rows in set, 1 warning (0.03 sec)

id不相同,如果是子查询,id的序号会递增,id的值越大被执行的优先级越高

mysql> EXPLAIN SELECT * FROM employees emp
    -> WHERE emp.emp_no NOT IN ( SELECT de.emp_no FROM dept_emp de
    -> WHERE de.dept_no NOT IN ( SELECT dept_no FROM departments WHERE dept_name = 'Development'));
+----+-------------+-------------+------------+-------+-------------------+-----------+---------+-------+--------+----------+--------------------------+
| id | select_type | table       | partitions | type  | possible_keys     | key       | key_len | ref   | rows   | filtered | Extra                    |
+----+-------------+-------------+------------+-------+-------------------+-----------+---------+-------+--------+----------+--------------------------+
|  1 | PRIMARY     | emp         | NULL       | ALL   | NULL              | NULL      | NULL    | NULL  | 299468 |   100.00 | Using where              |
|  2 | SUBQUERY    | de          | NULL       | index | PRIMARY           | dept_no   | 12      | NULL  | 308493 |   100.00 | Using where; Using index |
|  3 | SUBQUERY    | departments | NULL       | const | PRIMARY,dept_name | dept_name | 122     | const |      1 |   100.00 | Using index              |
+----+-------------+-------------+------------+-------+-------------------+-----------+---------+-------+--------+----------+--------------------------+
3 rows in set, 1 warning (0.00 sec)

id相同和不相同都存在

如果id相同可以认为是一组,同一组id执行顺序由上至下,不同组之间,id值越大被执行的优先级越高。

mysql> EXPLAIN SELECT * FROM employees emp
    -> WHERE emp.emp_no IN ( SELECT de.emp_no FROM dept_emp de
    -> WHERE de.dept_no IN ( SELECT dept_no FROM departments WHERE dept_name LIKE '%Develop%'));
+----+--------------+-------------+------------+-------+-----------------+-----------+---------+-------------------------------+--------+----------+----------------------------------------------------+
| id | select_type  | table       | partitions | type  | possible_keys   | key       | key_len | ref                           | rows   | filtered | Extra                                              |
+----+--------------+-------------+------------+-------+-----------------+-----------+---------+-------------------------------+--------+----------+----------------------------------------------------+
|  1 | SIMPLE       | <subquery2> | NULL       | ALL   | NULL            | NULL      | NULL    | NULL                          |   NULL |   100.00 | NULL                                               |
|  1 | SIMPLE       | emp         | NULL       | ALL   | PRIMARY         | NULL      | NULL    | NULL                          | 299468 |     0.00 | Using where; Using join buffer (Block Nested Loop) |
|  2 | MATERIALIZED | departments | NULL       | index | PRIMARY         | dept_name | 122     | NULL                          |      9 |    11.11 | Using where; Using index                           |
|  2 | MATERIALIZED | de          | NULL       | ref   | PRIMARY,dept_no | dept_no   | 12      | employees.departments.dept_no |  38561 |   100.00 | Using index                                        |
+----+--------------+-------------+------------+-------+-----------------+-----------+---------+-------------------------------+--------+----------+----------------------------------------------------+
4 rows in set, 1 warning (0.01 sec)

2.2 select_type

查询的类型,主要用来区别普通查询,联合查询,子查询等复杂查询。

包含SIMPLE、PRIMARY、UNION、DEPENDENT UNION、UNION RESULT、SUBQUERY、DEPENDENT SUBQUERY、DERIVED、MATERIALIZED、UNCACHEABLE SUBQUERY、UNCACHEABLE UNION

SIMPLE

简单的SELECT,不使用UNION或子查询。

mysql> EXPLAIN select * from employees where emp_no=10001;
+----+-------------+-----------+------------+-------+---------------+---------+---------+-------+------+----------+-------+
| id | select_type | table     | partitions | type  | possible_keys | key     | key_len | ref   | rows | filtered | Extra |
+----+-------------+-----------+------------+-------+---------------+---------+---------+-------+------+----------+-------+
|  1 | SIMPLE      | employees | NULL       | const | PRIMARY       | PRIMARY | 4       | const |    1 |   100.00 | NULL  |
+----+-------------+-----------+------------+-------+---------------+---------+---------+-------+------+----------+-------+
1 row in set, 1 warning (0.00 sec)

PRIMARY

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

mysql> EXPLAIN SELECT * FROM employees emp
    -> WHERE emp.emp_no IN ( SELECT max(emp_no) FROM dept_emp);
+----+--------------------+-------+------------+------+---------------+------+---------+------+--------+----------+------------------------------+
| id | select_type        | table | partitions | type | possible_keys | key  | key_len | ref  | rows   | filtered | Extra                        |
+----+--------------------+-------+------------+------+---------------+------+---------+------+--------+----------+------------------------------+
|  1 | PRIMARY            | emp   | NULL       | ALL  | NULL          | NULL | NULL    | NULL | 299468 |   100.00 | Using where                  |
|  2 | DEPENDENT SUBQUERY | NULL  | NULL       | NULL | NULL          | NULL | NULL    | NULL |   NULL |     NULL | Select tables optimized away |
+----+--------------------+-------+------------+------+---------------+------+---------+------+--------+----------+------------------------------+
2 rows in set, 1 warning (0.00 sec)

UNION

第二个或更靠后的 SELECT 语句出现在 UNION 之后,则被标记为 UNION

mysql> EXPLAIN (SELECT emp_no,dept_no FROM dept_emp LIMIT 10)
    -> UNION
    -> SELECT emp_no,dept_no FROM dept_manager;
+----+--------------+--------------+------------+-------+---------------+---------+---------+------+--------+----------+-----------------+
| id | select_type  | table        | partitions | type  | possible_keys | key     | key_len | ref  | rows   | filtered | Extra           |
+----+--------------+--------------+------------+-------+---------------+---------+---------+------+--------+----------+-----------------+
|  1 | PRIMARY      | dept_emp     | NULL       | index | NULL          | dept_no | 12      | NULL | 308493 |   100.00 | Using index     |
|  2 | UNION        | dept_manager | NULL       | index | NULL          | dept_no | 12      | NULL |     24 |   100.00 | Using index     |
| NULL | UNION RESULT | <union1,2>   | NULL       | ALL   | NULL          | NULL    | NULL    | NULL |   NULL |     NULL | Using temporary |
+----+--------------+--------------+------------+-------+---------------+---------+---------+------+--------+----------+-----------------+
3 rows in set, 1 warning (0.00 sec)

DEPENDENT UNION

与 UNION 相同,它出现在 UNION 或 UNION ALL语句中,但是此查询受外部查询的影响

| UNION RESULT union_result Result of a UNION.
| SUBQUERY None First SELECT in subquery
| DEPENDENT SUBQUERY dependent (true) First SELECT in subquery, dependent on outer query
| DERIVED None Derived table
| MATERIALIZED materialized_from_subquery Materialized subquery
| UNCACHEABLE SUBQUERY cacheable (false) A subquery for which the result cannot be cached and must be re-evaluated for each row of the outer query
| UNCACHEABLE UNION cacheable (false) The second or later select in a UNION that belongs to an uncacheable subquery (see UNCACHEABLE SUBQUERY)

总结

到此这篇关于MySQL EXPLAIN输出列的文章就介绍到这了,更多相关MySQL EXPLAIN输出列内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 详解MySQL中EXPLAIN解释命令及用法讲解

    1,情景描述:同事教我在mysql中用explain,于是查看了一番返回内容的含义 2,现就有用处的内容做如下记录: 1,explain显示了mysql如何使用索引来处理select语句以及连接表.可以帮助选择更好的索引和写出更优化的查询语句. 使用方法,在select语句前加上explain就可以了: explain select count(DISTINCT uc_userid) as user_login from user_char_daily_gameapp_11 where uc_d

  • mysql总结之explain

    explain主要用于sql语句中的select查询,可以显示的查看该sql语句索引的命中情况,从而更好的利用索引.优化查询效率. Explain语法如下:explain [extended] select ... 其中extended是选用的,如果使用的extended,那么explain之后就可以使用show warnings查看相应的优化信息,也就是mysql内部实际执行的query. 列名 描述 说明 相关链接 id 若没有子查询和联合查询,id则都是1. Mysql会按照id从大到小的

  • MySQL性能分析及explain的使用说明

    1.使用explain语句去查看分析结果 如explain select * from test1 where id=1;会出现:id selecttype table type possible_keys key key_len ref rows extra各列. 其中, type=const表示通过索引一次就找到了: key=primary的话,表示使用了主键: type=all,表示为全表扫描: key=null表示没用到索引.type=ref,因为这时认为是多个匹配行,在联合查询中,一般

  • MYSQL explain 执行计划

    使用方法,在select语句前加上explain就可以了: 如:explain select * from test1 EXPLAIN列的解释: table:显示这一行的数据是关于哪张表的 type:这是重要的列,显示连接使用了何种类型.从最好到最差的连接类型为const.eq_reg.ref.range.indexhe和ALL possible_keys:显示可能应用在这张表中的索引.如果为空,没有可能的索引.可以为相关的域从WHERE语句中选择一个合适的语句 key: 实际使用的索引.如果为

  • mysql之explain使用详解(分析索引)

    explain显示了mysql如何使用索引来处理select语句以及连接表.可以帮助选择更好的索引和写出更优化的查询语句. 使用方法,在select语句前加上explain就可以了,如: explain select * from statuses_status where id=11; explain列的解释 table:显示这一行的数据是关于哪张表的 type:这是重要的列,显示连接使用了何种类型.从最好到最差的连接类型为const.eq_reg.ref.range.indexhe和all

  • MySQL中执行计划explain命令示例详解

    前言 explain命令是查看查询优化器如何决定执行查询的主要方法. 这个功能有局限性,并不总会说出真相,但它的输出是可以获取的最好信息,值得花时间去了解,因为可以学习到查询是如何执行的. 调用EXPLAIN 在select之前添加explain,mysql会在查询上设置一个标记,当执行查询计划时,这个标记会使其返回关于执行计划中每一步的信息,而不是执行它. 它会返回一行或多行信息,显示出执行计划中的每一部分和执行次序. 这是一个简单的explain效果: 在查询中每个表在输出只有一行,如果查询

  • Mysql中explain作用详解

    一.MYSQL的索引 索引(Index):帮助Mysql高效获取数据的一种数据结构.用于提高查找效率,可以比作字典.可以简单理解为排好序的快速查找的数据结构. 索引的作用:便于查询和排序(所以添加索引会影响where 语句与 order by 排序语句). 在数据之外,数据库还维护着满足特定查找算法的数据结构,这些数据结构以某种方式引用数据.这样就可以在这些数据结构上实现高级查找算法.这些数据结构就是索引. 索引本身也很大,不可能全部存储在内存中,所以索引往往以索引文件的形式存储在磁盘上. 我们

  • mysql中explain用法详解

    如果在select语句前放上关键词explain,mysql将解释它如何处理select,提供有关表如何联接和联接的次序. explain的每个输出行提供一个表的相关信息,并且每个行包括下面的列: 1,id   select识别符.这是select的查询序列号.2,select_type 可以为一下任何一种类型simple  简单select(不使用union或子查询)primary   最外面的selectunion    union中的第二个或后面的select语句dependent uni

  • MySQL查询优化之explain的深入解析

    在分析查询性能时,考虑EXPLAIN关键字同样很管用.EXPLAIN关键字一般放在SELECT查询语句的前面,用于描述MySQL如何执行查询操作.以及MySQL成功返回结果集需要执行的行数.explain 可以帮助我们分析 select 语句,让我们知道查询效率低下的原因,从而改进我们查询,让查询优化器能够更好的工作. 一.MySQL 查询优化器是如何工作的MySQL 查询优化器有几个目标,但是其中最主要的目标是尽可能地使用索引,并且使用最严格的索引来消除尽可能多的数据行.最终目标是提交 SEL

  • MySQL中EXPLAIN命令详解

    explain显示了mysql如何使用索引来处理select语句以及连接表.可以帮助选择更好的索引和写出更优化的查询语句. 使用方法,在select语句前加上explain就可以了: 如: 复制代码 代码如下: explain select surname,first_name form a,b where a.id=b.id EXPLAIN列的解释: table:显示这一行的数据是关于哪张表的 type:这是重要的列,显示连接使用了何种类型.从最好到最差的连接类型为const.eq_reg.r

随机推荐