直观理解:MySQL EXPLAIN
在工作中呢我们常常会遇到慢sql需要优化的问题,这个时候通常我们需要用到explain
来查看一个SQL语句的详细执行计划,以查看该SQL是否使用了索引,有没有进行全表扫描等,然后再根据执行计划,多当前SQL进行优化,或者为表的若干字段添加索引等。explain
命令并不会真正执行当前SQL返回业务数据,而是返回当前SQL的执行计划。这里简单的介绍以下explain
命令的执行结果和每个字段的意义。下面我们给出几个explain
的示例。
explain
select min(score)
from exam_record
left join examination_info using(exam_id)
where tag = 'SQL' and score >=(
select avg(score)
from exam_record
left join examination_info using(exam_id)
where tag = 'SQL'
)

EXPLAIN
select
uid,
'activity1' as activity
from
exam_record
inner join examination_info using(exam_id)
where
year(start_time) = 2021
group by
uid
having
min(score) >= 85
union all
select
distinct uid,
'activity2' as activity
from
exam_record
inner join examination_info using(exam_id)
where
year(start_time) = 2021
and difficulty = 'hard'
and score >= 80
and timestampdiff(minute, start_time, submit_time) * 2 < duration
order by uid

explain
的执行结果会返回十几个个字段,这个十二字段如上图所示,分别是:id
、select_type
、table
、partitions
、type
、possible_keys
、key
、key_len
、ref
、rows
、filtered
和Extra
。下面会依次介绍每个字段的详细意义。
id
id
表示的是select
查询语句的序号,代表了SQL语句执行的顺序,SQL按照id
从大到小执行,id
相同的为一组,从上到下执行。例如上图的SQL先执行子查询外部的查询语句,然后再执行子查询。
select_type
select_type
表示查询的类型,也就是对应的是简单查询还是复杂查询,若是复杂查询则又包含简单的子查询、from
子句的子查询、union
查询等。下面就分别来看看select_type
中的所有查询类型。
- SIMPLE: 简单的
select
查询,未使用union
或子查询等复杂查询。 - PRIMARY:复杂查询中的最外层的
select
的类型就是PRIMARY。 - SUBQUERY:子查询中的
select
语句的类型。 - DEPENDENT SUBQUERY:子查询中的第一个
select
,依赖于外部查询。 - UNCACHEABLE SUBQUERY:一个子查询的结果不能被缓存,必须重新评估外链接的第一行。
- UNION:在
union
语句中的第二个或后面的select
语句的类型。 - UNION RESULT:UNION查询语句的结果
- DEPENDENT UNION:表示
union
中的第二个或后面的select
语句,取决于外面的查询。 - DERIVED:派生表的
select
,from
子句的子查询。
table
table
表示查询数据来源与哪张表,若未使用别名,则为表名,若使用别名,则为别名。既可以表示已经存在表,又可以表示衍生表。
partitions
partitions
表示的是分区信息,如果查询是基于分区表的话,会显示查询将访问的分区。
type
type
表示访问类型或连接类型,即MySQL决定如何查找表中的行。type
是MySQL查询优化中一个很重要的指标,访问性能从最优到最差分别为:system
> const
> eq_ref
> ref
> fulltext
> ref_or_null
> index_merge
> unique_subquery
> index_subquery
> range
> index
> ALL
,连接性能从最优到最差分别为:const
> eq_ref
> ref
> range
> index
> ALL
。
possible_keys
possible_keys
指出如果MySQL能使用该索引在表中找到记录,查询涉及到的字段上若存在索引,则该索引将被列出,但不一定被查询使用。即该查询可以利用的索引,如果没有任何可利用的索引则显示为NULL
。
key
key
列显示MySQL实际在执行中会使用的索引,如果使用则必然包含在possible_keys
中,因为possible_keys
中列出了所有可能用于查出结果的索引信息。若实际执行中不使用索引,则为NULL
。如果要想强制MySQL使用或忽视possible_keys
中的索引,则需要在查询中使用force index
、use index
或者ignore index
。
key_len
key_len
表示索引中使用的字节数,查询中使用的索引的长度(最大可能长度),并非实际使用长度,理论上长度越短越好。
ref
ref
表示列与索引的比较,表连接的匹配条件,表示哪些列或者常量被用于查询索引列上的值。
rows
rows
表示估算的要扫描的行数,一般Mysql会根据统计表信息和索引的选用情况,估算出查找记录所要扫描的行数,注意这个并不是实际结果集的行数。
filtered
filtered
表示当前查询返回的数据在server层过滤后,剩下多少满足查询的记录数量的比例,表示的是查询表行在表中的占比。
Extra
Extra
表示的信息非常多,日后再说~~