- 前言
一个程序员 对每个SQL语句 进行explain分析是基本的素养。Explain概述
- 使用 EXPLAIN 关键字可以模拟优化器执行 SQL 查询语句,从而知道 MySQL 是如何处理你的 SQL 语句的。分 析你的查询语句或是表结构的性能瓶颈。 可以帮助选择更好的索引和写出更优化的查询语句。
- 基本结构
id
- id是SQL语句执行的查询顺序,表示查询中执行的select子句或操作表的顺序
- 一共分为三种情况
- id相同时:sql语句执行顺序 是由上至下。即可能会有几条select语句的id相同。在相同的id的情况下,这几条语句的执行顺序是由上至下的。
- id不同的情况: 如果是子查询,id的序号会递增,id值越大优先级越高,也就是说 id大的select语句,会被优先的执行
select_type
- 示查询中每个select子句的类型
(1) SIMPLE(简单SELECT,不使用UNION或子查询等): 简单的SQL查询,这种查询不包含子查询或者UNION
(2) PRIMARY(查询中若包含任何复杂的子部分,最外层的select被标记为PRIMARY)
(3) UNION:若第二select语句出现在union之后, 那么这个select查询类型就会被标记为union;
若union包含在from子句的子查询中,外层select查询将被标记为DERIVED .
(4) DEPENDENT UNION(UNION中的第二个或后面的SELECT语句,取决于外面的查询)
(5) UNION RESULT(UNION的结果)
(6) SUBQUERY(子查询中的第一个SELECT)
(7) DEPENDENT SUBQUERY(子查询中的第一个SELECT,取决于外面的查询)
(8) DERIVED(派生表的SELECT, FROM子句的子查询):在from列表里包含的子查询被标记为DERIVED(衍生),MYSQL递归执行这些子查询,并把查询结果存放到临时表里面。
(9) UNCACHEABLE SUBQUERY(一个子查询的结果不能被缓存,必须重新评估外链接的第一行)
type
- 表示显示查询使用的访问类型。类型排序 system>const>eq_ref>ref>range>index>ALL
常用的类型有: ALL, index, range, ref, eq_ref, const, system, NULL(从左到右,性能从差到好)
ALL:Full Table Scan, MySQL将遍历全表以找到匹配的行,所以在实际开发中,尽量不要使用select*。 因为这种查询是使用全部查询。
index: Full Index Scan,index与ALL区别为index类型只遍历索引树。即mysql通过索引查询数据。直接从根节点搜索数据。节点值与查找值 进行比较查找。
range:只检索给定范围的行,使用一个索引来选择行。:即进行范围的查找。 key列显示使用哪个索引,一般是在where语句中出现了between,<>,in等的查询。这种范围扫描索引比全表扫描要好,因为只需要开始于索引的某一点,结束于另一点,不用扫描全部的索引。
ref: 表示上述表的连接匹配条件,即哪些列或常量被用于查找索引列上的值。非唯一性索引扫描,返回匹配某个单独值的所有行。本质也是一种所有访问。
eq_ref: 类似ref,区别就在使用的索引是唯一索引,对于每个索引键值,表中只有一条记录匹配,简单来说,就是多表连接中使用primary key或者 unique key作为关联条件
const、system: 当MySQL对查询某部分进行优化,并转换为一个常量时,使用这些类型访问。如将主键置于where列表中,MySQL就能将该查询转换为一个常量,system是const类型的特例,当查询的表只有一行的情况下,使用system
NULL: MySQL在优化过程中分解语句,执行时甚至不用访问表或索引,例如从一个索引列里选取最小值可以通过单独索引查找完成。
possible_key AND key
- possible_key : 显示可能应用在这张表中的索引,一个或多个。查询涉及到的字段上若存在索引,则该索引将被列出,但不一定被查询使用。
- key :实际使用的索引。如果为null,则没有使用索引。查询中若使用了覆盖索引,则该索引仅出现在key列表中。
- key_ len: 索引的最大长度,显示的值为索引字段的最大可能长度,但并非实际使用长度。
ref
- 显示索引的哪一列 被使用了,如果可能的话,是一个常数。哪些列或常量被用于查找所有列上的值。 告诉使用者,有没有使用到索引,以及是使用的哪一个索引。(被实际使用的索引)
row
- 根据表统计信息,及其索引选用情况,大致估算找到所需要的读取的行数。
Extra
-
该列包含MySQL解决查询的详细信息,有以下几种情况:
-
Using where:列数据是从仅仅使用了索引中的信息而没有读取实际的行动的表返回的,这发生在对表的全部的请求列都是同一个索引的部分的时候,表示mysql服务器将在存储引擎检索行后再进行过滤
-
Using temporary:表示MySQL需要使用临时表来存储结果集,常见于排序和分组查询
-
Using filesort:MySQL中无法利用索引完成的排序操作称为“文件排序”。----->这是查询最糟糕的情况
-
Using index:表示是使用的索引查找。如果同时出现了using where 表明索引被用来执行索引键值的查找。--------》最好的情况
-
Using join buffer:改值强调了在获取连接条件时没有使用索引,并且需要连接缓冲区来存储中间结果。如果出现了这个值,那应该注意,根据查询的具体情况可能需要添加索引来改进能。
-
Impossible where:这个值强调了where语句会导致没有符合条件的行。
-
Select tables optimized away:这个值意味着仅通过使用索引,优化器可能仅从聚合函数结果中返回一行‘
什么是覆盖索引?
- 当我们使用的select语句查询数据时,查询的数据恰好是索引列对应的数据,没有查询其他的数据行,这就是覆盖索引。