对MySQL索引进行优化时,有一个神器,就是explain命令(也可以使用DESC命令,效果一样),下面简单介绍下explain命令。
explain命令可以模拟优化器执行SQL查询语句,从而知道MySQL是如何处理SQL语句的可以帮我们分析SQL语句或者表结构的性能瓶颈。通过explain命令,我们可以得到:
- 表的读取顺序
- 数据读取操作的操作类型
- 哪些索引可能使用
- 哪些索引被实际使用
- 表之间的连接
- 每张表有多少行被优化器查询
命令结果
列的说明:
id:
id是一组数字,表示查询中执行select子句或者操作表的顺序,如果id相同,则执行顺序从上至下,如果是子查询,id的序号会递增,id越大则优先级越高,越先会被执行。id列为NULL则表示这是一个结果集,不需要使用它来查询。
select_type: 表示查询类型,具体如下:
SIMPLE:简单查询(不使用连接或子查询)
PRIMARY:最外层的查询
UNION: 连接中第二个或者之后的子查询
DEPENDENT
UNION:连接中第二个或者之后的子查询(依赖于外部表查询)
UNION RESULT:连接的结果
SUBQUERY:子查询中的第一个查询
DEPENDENT
SUBQUERY:子查询中的第一个查询(依赖于外部表查询)
DERIVED:派生表查询(from子句中的子查询)
MATERIALIZED:被物化的子查询
UNCACHEABLE
SUBQUERY:结果不能被缓存并且必须为外部查询的每一行重新评估的子查询
UNCACHEABLE UNION:The second or
later select in a UNION that belongs to an uncacheable
subquery
[注]依赖通常意味着使用相关子查询
table:表示查询的表名,如果查询使用了别名,那么这里显示别名
type:表示join类型,依次从好到差:system,const,eq_ref,ref,fulltext,ref_or_null,unique_subquery,index_subquery,range,index_merge,index,ALL。除了all之外,其他的type都可以使用到索引,除了index_merge之外,其他的type只可以用到一个索引。具体如下:
system:表中只有一行数据或空表,
只能用于myisam和memory表。如果是Innodb引擎表,type列在这个情况通常都是all或者index。
const:表最多只有一行匹配,使用唯一索引或者主键。
eq_ref:
从该表读取一行为了之前表的数据行的每一个组合,出现在连接多个表的查询中,当索引的所有部分都被连接使用并且该索引是一个主键或者唯一非空索引时使用。
ref:
所有有匹配的索引值的行是从之前表的数据行的每一个组合中读取的,如果该连接仅仅使用键的最左前缀或者该键不是主键或唯一索引时使用。
fulltext: 连接使用FULLTEXT索引。
ref_or_null:
跟ref类似,但是额外查询含有NULL值的行。
index_merge: 表明使用了索引合并优化。
unique_subquery:
这种类型在某些如下形式的IN子查询中替换eq_ref:
value IN (SELECT primary_key FROM
single_table WHERE some_expr)
index_subquery:
这种连接类型类似于unique_subquery,只是它对子查询中非唯一索引起作用,形式如下:
value IN (SELECT key_column FROM single_table WHERE
some_expr)
range: 仅当给定范围内的行被检索到,使用索引来选择这些行。可以使用=,
<>, >,
>=,
<=>, BETWEEN, or IN()这些操作符。
index: 当查询只使用单个索引列的一部分时使用。
ALL: 全表扫描。
possible_keys: 可能使用到的索引
key:
实际使用的索引,select_type为index_merge时,这里可能出现两个以上的索引,其他的select_type这里只会出现一个。
key_len: 选择的键的长度
ref:
如果使用常数等值查询,这里会显示const,如果是连接查询,这里会显示关联字段,如果是条件使用了表达式或者函数或者条件列发生了内部隐式转换,这里可能显示为func。
rows: 估计需要检查的行数,不精确
Extra: 额外信息,有几十种,常用的有:
distinct: 在select部分使用了distinc关键字
using filesort:
排序时无法使用到索引时,就会出现这个。常见于order by和group by语句中。
using
index:查询时不需要回表查询,直接通过索引就可以获取查询的数据。
using_union:表示使用or连接各个使用索引的条件时,该信息表示从处理结果获取并集
using
where:表示存储引擎返回的记录并不是所有的都满足查询条件,需要在server层进行过滤。
using temporary:表示使用了临时表存储中间结果。
filtered:使用explain
extended时会出现这个列,5.7之后的版本默认就有这个字段,不需要使用explain
extended了。这个字段表示存储引擎返回的数据在server层过滤后,剩下多少满足查询的记录数量的比例,注意是百分比,不是具体记录数。
参考官方文档:
https://dev.mysql.com/doc/refman/5.7/en/explain-output.html#explain_extra