mysql使用explain xxx可以分析sql语句的性能,本文详细总结一下每个字段的意义

MYSQL 5.6.3以前只能EXPLAIN SELECT; MYSQL5.6.3以后就可以EXPLAIN SELECT,UPDATE,DELETE

概述

首先看一个简单的示例

mysql> explain select * from staff;
+----+-------------+-------+------+---------------+------+---------+------+------+-------+
| id | select_type | table | type | possible_keys | key  | key_len | ref  | rows | Extra |
+----+-------------+-------+------+---------------+------+---------+------+------+-------+
|  1 | SIMPLE      | staff | ALL  | NULL          | NULL | NULL    | NULL |    2 | NULL  |
+----+-------------+-------+------+---------------+------+---------+------+------+-------+
1 row in set

先总结下所有字段的意义

column 含义
id 查询序号
select_type 查询类型
table 表名
type join类型
prossible_keys 可能会选择的索引
key 实际选择的索引
key_len 索引的长度
ref 与索引作比较的列
rows 要检索的行数(估算值)
Extra 额外信息

再详细介绍每个字段的意义

1. id

SQL查询中的序列号

id列数字越大越先执行,如果说数字一样大,那么就从上往下依次执行

例如:

mysql> explain select * from (select * from ( select * from t3 where id=3952602) a) b;
+----+-------------+------------+--------+-------------------+---------+---------+------+------+-------+
| id | select_type | table      | type   | possible_keys     | key     | key_len | ref  | rows | Extra |
+----+-------------+------------+--------+-------------------+---------+---------+------+------+-------+
|  1 | PRIMARY     | <derived2> | system | NULL              | NULL    | NULL    | NULL |    1 |       |
|  2 | DERIVED     | <derived3> | system | NULL              | NULL    | NULL    | NULL |    1 |       |
|  3 | DERIVED     | t3         | const  | PRIMARY,idx_t3_id | PRIMARY | 4       |      |    1 |       |
+----+-------------+------------+--------+-------------------+---------+---------+------+------+-------+

sql语句从内到外按照id的顺序3 => 2 => 1依次执行

2. select_type

查询的类型,可以是下表的任何一种类型

select_type 类型说明
SIMPLE 简单SELECT(不使用UNION或子查询)
PRIMARY 最外层的SELECT
UNION UNION中第二个或之后的SELECT语句
DEPENDENT UNION UNION中第二个或之后的SELECT语句取决于外面的查询
UNION RESULT UNION的结果
SUBQUERY 子查询中的第一个SELECT
DEPENDENT SUBQUERY 子查询中的第一个SELECT, 取决于外面的查询
DERIVED 衍生表(FROM子句中的子查询)
MATERIALIZED 物化子查询
UNCACHEABLE SUBQUERY 结果集无法缓存的子查询,必须重新评估外部查询的每一行
UNCACHEABLE UNION UNION中第二个或之后的SELECT,属于无法缓存的子查询

SIMPLE示例:

mysql> explain select * from t3 where id=3952602;
+----+-------------+-------+-------+-------------------+---------+---------+-------+------+-------+
| id | select_type | table | type  | possible_keys     | key     | key_len | ref   | rows | Extra |
+----+-------------+-------+-------+-------------------+---------+---------+-------+------+-------+
|  1 | SIMPLE      | t3    | const | PRIMARY,idx_t3_id | PRIMARY | 4       | const |    1 |       |
+----+-------------+-------+-------+-------------------+---------+---------+-------+------+-------+

PRIMARY示例:

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

UNION、UNION RESULT示例:

mysql> explain select * from t3 where id=3952602 union all select * from t3 ;
+----+--------------+------------+-------+-------------------+---------+---------+-------+------+-------+
| id | select_type  | table      | type  | possible_keys     | key     | key_len | ref   | rows | Extra |
+----+--------------+------------+-------+-------------------+---------+---------+-------+------+-------+
|  1 | PRIMARY      | t3         | const | PRIMARY,idx_t3_id | PRIMARY | 4       | const |    1 |       |
|  2 | UNION        | t3         | ALL   | NULL              | NULL    | NULL    | NULL  | 1000 |       |
|NULL | UNION RESULT | <union1,2> | ALL   | NULL              | NULL    | NULL    | NULL  | NULL |       |
+----+--------------+------------+-------+-------------------+---------+---------+-------+------+-------+

3. table

查询的表名。不一定是实际存在的表。

可以为如下的值:

  • <unionM,N>: 引用idMN UNION后的结果。

  • <derivedN>: 引用idN的结果派生出的表。派生表可以是一个结果集,例如派生自FROM中子查询的结果。

  • <subqueryN>: 引用idN的子查询结果物化得到的表。即生成一个临时表保存子查询的结果。

例如:

mysql> explain select * from (select * from ( select * from t3 where id=3952602) a) b;
+----+-------------+------------+--------+-------------------+---------+---------+------+------+-------+
| id | select_type | table      | type   | possible_keys     | key     | key_len | ref  | rows | Extra |
+----+-------------+------------+--------+-------------------+---------+---------+------+------+-------+
|  1 | PRIMARY     | <derived2> | system | NULL              | NULL    | NULL    | NULL |    1 |       |
|  2 | DERIVED     | <derived3> | system | NULL              | NULL    | NULL    | NULL |    1 |       |
|  3 | DERIVED     | t3         | const  | PRIMARY,idx_t3_id | PRIMARY | 4       |      |    1 |       |
+----+-------------+------------+--------+-------------------+---------+---------+------+------+-------+

4. type(重要)

这是最重要的字段之一,显示查询使用了何种类型

下表从上到下性能依次递减

type 说明
system 表中只有一行数据或者是空表,这是const类型的一个特例。且只能用于myisammemory表。如果是Innodb引擎表,type列在这个情况通常都是all或者index
const 最多只有一行记录匹配。当联合主键或唯一索引的所有字段跟常量值比较时,join类型为const。其他数据库也叫做唯一索引扫描
eq_ref 多表join时,对于来自前面表的每一行,在当前表中只能找到一行。它用在一个索引的所有部分被联接使用并且索引是UNIQUEPRIMARY KEY
ref 对于来自前面表的每一行,在此表的索引中可以匹配到多行。
fulltext 使用全文索引的时候是这个类型。要注意,全文索引的优先级很高,若全文索引和普通索引同时存在时,mysql不管代价,优先选择使用全文索引
ref_or_null 该联接类型如同ref,但是添加了MySQL可以专门搜索包含NULL值的行
index_merge 表示查询使用了两个以上的索引,最后取交集或者并集,常见andor的条件使用了不同的索引
unique_subquery 用于where中的in形式子查询,子查询返回不重复值唯一值,可以完全替换子查询,效率更高。 该类型替换了下面形式的IN子查询的refvalue IN (SELECT primary_key FROM single_table WHERE some_expr)
index_subquery 该联接类型类似于unique_subquery。适用于非唯一索引,可以返回重复值。
range 索引范围查询,常见于使用 =, <>, >, >=, <, <=, IS NULL, <=>, BETWEEN, IN()或者like等运算符的查询中。比如:SELECT * FROM tbl_name WHERE key_column BETWEEN 10 and 20;
index 索引全表扫描,把索引从头到尾扫一遍。这里包含两种情况: 一种是查询使用了覆盖索引,那么它只需要扫描索引就可以获得数据,这个效率要比全表扫描要快,因为索引通常比数据表小,而且还能避免二次查询。在extra中显示Using index,反之,如果在索引上进行全表扫描,没有Using index的提示。
ALL 全表扫描,性能最差

const示例:

mysql> explain select * from t3 where id=3952602;
+----+-------------+-------+-------+-------------------+---------+---------+-------+------+-------+
| id | select_type | table | type  | possible_keys     | key     | key_len | ref   | rows | Extra |
+----+-------------+-------+-------+-------------------+---------+---------+-------+------+-------+
|  1 | SIMPLE      | t3    | const | PRIMARY,idx_t3_id | PRIMARY | 4       | const |    1 |       |
+----+-------------+-------+-------+-------------------+---------+---------+-------+------+-------+

eq_ref示例:

mysql> create unique index  idx_t3_id on t3(id) ;
Query OK, 1000 rows affected (0.03 sec)
Records: 1000  Duplicates: 0  Warnings: 0mysql> explain select * from t3,t4 where t3.id=t4.accountid;
+----+-------------+-------+--------+-------------------+-----------+---------+----------------------+------+-------+
| id | select_type | table | type   | possible_keys     | key       | key_len | ref                  | rows | Extra |
+----+-------------+-------+--------+-------------------+-----------+---------+----------------------+------+-------+
|  1 | SIMPLE      | t4    | ALL    | NULL              | NULL      | NULL    | NULL                 | 1000 |       |
|  1 | SIMPLE      | t3    | eq_ref | PRIMARY,idx_t3_id | idx_t3_id | 4       | dbatest.t4.accountid |    1 |       |
+----+-------------+-------+--------+-------------------+-----------+---------+----------------------+------+-------+

index_merge示例:

mysql> explain select * from t4 where id=3952602 or accountid=31754306 ;
+----+-------------+-------+-------------+----------------------------+----------------------------+---------+------+------+------------------------------------------------------+
| id | select_type | table | type        | possible_keys              | key                        | key_len | ref  | rows | Extra                                                |
+----+-------------+-------+-------------+----------------------------+----------------------------+---------+------+------+------------------------------------------------------+
|  1 | SIMPLE      | t4    | index_merge | idx_t4_id,idx_t4_accountid | idx_t4_id,idx_t4_accountid | 4,4     | NULL |    2 | Using union(idx_t4_id,idx_t4_accountid); Using where |
+----+-------------+-------+-------------+----------------------------+----------------------------+---------+------+------+------------------------------------------------------+

range示例:

mysql> explain SELECT * FROM t3 WHERE id BETWEEN 10 and 1000;
+----+-------------+-------+-------+-------------------+-----------+---------+------+------+-------------+
| id | select_type | table | type  | possible_keys     | key       | key_len | ref  | rows | Extra       |
+----+-------------+-------+-------+-------------------+-----------+---------+------+------+-------------+
|  1 | SIMPLE      | t3    | range | PRIMARY,idx_t3_id | idx_t3_id | 4       | NULL |    2 | Using where |
+----+-------------+-------+-------+-------------------+-----------+---------+------+------+-------------+

5. possible_keys

查询可能使用到的索引都会在这里列出来

6. key

查询真正使用到的索引。

select_typeindex_merge时,这里可能出现两个以上的索引,其他的select_type这里只会出现一个。

7. key_len

查询用到的索引长度(字节数)

如果是单列索引,那就整个索引长度算进去,如果是多列索引,那么查询不一定都能使用到所有的列,用多少算多少。

在不损失精确性的情况下,长度越短越好

key_len只计算where条件用到的索引长度,而排序和分组就算用到了索引,也不会计算到key_len

8. ref

和前方表连接的字段

如果是使用的常数等值查询,这里会显示const,如果是连接查询,被驱动表的执行计划这里会显示驱动表的关联字段,如果是条件使用了表达式或者函数,或者条件列发生了内部隐式转换,这里可能显示为func

9. rows(重要)

这是mysql估算的需要扫描的行数(不是精确值)。

这个值非常直观显示 SQL 的效率好坏, 原则上 rows 越少越好.

10. Extra(重要)

EXplain 中的很多额外的信息会在 Extra 字段显示, 常见的有以下几种内容:

Extra 说明
Distinct 一旦找到了与行相联合匹配的行,就不再搜索了。在select部分使用了distinc关键字会出现
Using filesort 表示需额外的排序操作, 不能通过索引顺序达到排序效果。看到这个的时候,查询就需要优化了。
Using index “覆盖索引扫描”, 表示查询在索引树中就可查找所需数据, 不用扫描表数据文件, 往往说明性能不错
Using temporary 查询有使用临时表, 一般出现于排序, 分组和多表 join 的情况, 查询效率不高, 建议优化.

以上就是explain各个字段的意义,这里一般做个进阶了解

在实际开发中,为了提升开发效率,我们可以选择搭配一些可视化SQL优化工具使用,可以参考我的这篇文章《小白也会用的SQL优化工具推荐》

EXPLAIN各个字段是什么意思相关推荐

  1. SQL语句中explain各字段含义

    SQL语句中explain各字段含义 1 id: 2 select_type 3 type 4 table 5 possible_keys 6 Key key列显示MySQL实际决定使用的键(索引) ...

  2. 22-08-25 MySQL高级(03)MySQL索引、索引演绎、适合加索引的情况、执行计划Explain各字段解释

    "系统,那如果我没有绑定,没有简化,我原先的人生最大的可能是怎么样的",李长生好奇一问.很快系统给出了答案. "如果宿主是小说主角的话,就活个几章" " ...

  3. Mysql Explain 结果字段解释

    2019独角兽企业重金招聘Python工程师标准>>> Explain结果的每行记录显示了每个表的相关信息,每行记录都包含以下几个字段: id 本次 select 的标识符, 并没有 ...

  4. MySQL进阶系列: 一文详解explain各字段含义

    explain有何用处呢:为了知道优化SQL语句的执行,需要查看SQL语句的具体执行过程,以加快SQL语句的执行效率. 可以使用explain+SQL语句来模拟优化器执行SQL查询语句,从而知道mys ...

  5. mysql字段名explain_Mysql中explain用法和结果字段的含义介绍

    做一个积极的人 编码.改bug.提升自己 我有一个乐园,面向编程,春暖花开 分享一下大神老师的人工智能教程.零基础!通俗易懂!风趣幽默(偶尔开开车,讲讲黄段子)! 大家可以看看是否对自己有帮助,如果你 ...

  6. MYSQL:explain分析

    mysql explain分析 通过explain可以知道mysql是如何处理语句,分析出查询或是表结构的性能瓶颈.通过expalin可以得到: 1. 表的读取顺序 2.表的读取操作的操作类型 3.哪 ...

  7. MySQL怎么打开explain_MySQL干货之-利用EXPLAIN优化查询

    ​ 在工作中,经常会碰到一些慢查询,Explain可以帮我们更详细的了解MySQL查询的执行计划,用法也很简单Explain 后面跟上SELECT语句即可.执行完之后,会显示一行有多个列的记录,可能很 ...

  8. DECRIBE / EXPLAIN

    用于查看特定表的详细设计信息 EXPLAIN cls_tb cls_name; DESCRIBE cls_tb cls_name; DESCRIBE/EXPLAIN 表 字段; 结果:

  9. MySQL explain 命令

    概述 MySQL 的 explain 命令,主要用于查看实际查询过程中的一些执行细节(执行计划),也是查看优化器决定如何执行查询的主要方法 explain 使用示例 explain 的使用也很简单,在 ...

  10. MySQL 优化 —— EXPLAIN 执行计划详解

    引言 本博客大部分内容翻译自MySQL 官网 Understanding the Query Execution Plan 专题.另外有一些补充,则来自于网课以及<高性能MySQL(第三版)&g ...

最新文章

  1. mac mini 装UBUNTU后没有WIFI解决办法
  2. Linux命令 crontab的理解和使用方法
  3. java各种容器内部实现原理
  4. Linux 让进程在后台可靠运行的几种方法
  5. OpenCASCADE:建立Body
  6. 支付宝新版SDK-PC扫码支付-手机浏览器H5支付
  7. 校园综合服务平台小程序
  8. 由汉诺塔引起的对递归的思考
  9. ubuntu 安装java_Hadoop3.1.3安装教程_单机/伪分布式配置
  10. php5 mysql怎样下载,PHP5操作MySQL数据库(5)
  11. PECL PEAR php扩展模块的简便安装方式
  12. javaScript深克隆(deepClone(origin,target))
  13. Apache下设置整站变灰方法
  14. ATP-EMTP电缆LCC模型中相数与电缆数的设置
  15. Linux递归统计当前目录下普通文件的数量
  16. 深圳最牛街道办:腾讯华为设总部,百家上市公司年营收超2万亿
  17. 产品经理-自然资源行业4大产品线整理
  18. 路由器设备升级SNMP日志
  19. creo2.0+VS2010采用protoolkit二次开发环境配置(64位win7)
  20. PX Deq Credit: send blkd 等待事件

热门文章

  1. 在mysql中,涉及到金钱的数据类型一般是什么?
  2. 英语: 听力(Listening)
  3. 【电子学会】2019年12月图形化四级 -- 随机选T恤
  4. 一种简单的生成伪随机数的方法(翻译)
  5. H5viedo标签播放*.Mp4听得到音频却不显示视频的解决办法
  6. Compilation failed to complete
  7. Python教程:利用百度API进行批量图片OCR识别
  8. python opencv合并图片
  9. 职业规划-《你的降落伞是什么颜色》书中的精髓:如何挖掘自我优势,找到心仪的工作?
  10. 文件上传(WebUploader)成功之前自定义裁剪(vue-img-cutter),上传裁剪的图片,并兼容ie