Explain命令

explain用于获取查询相关的执行计划信息,在这个命令中可以知晓查询是如何执行的。

使用explain也很简单,只需要在所需分析的语句前加上explain执行即可。其输出结果如下:

******** 1. row ********
           id: 1
  select_type: SIMPLE
        table: cms_article
         type: ref
possible_keys: INDEX_CREATE
          key: INDEX_CREATE
      key_len: 259
          ref: const
         rows: 1
        Extra: Using index condition

id

这一列用于标识查询编号,如果没有子查询,那么每个索引都会标识为1。

select_type

这行标识了SELECT的类型,即简单查询还是复杂查询

SIMPLE:查询中不包含子查询和UNION查询,即简单查询

对于复杂查询

explain select v.id from (select id from cms_article where create_by = '1') v \G;

explain后会出现多行数据

************ 1. row ***********
           id: 1
  select_type: PRIMARY
        table: <derived2>
         type: ALL
possible_keys: NULL
          key: NULL
      key_len: NULL
          ref: NULL
         rows: 2
        Extra: NULL
************ 2. row ************
           id: 2
  select_type: DERIVED
        table: cms_article
         type: ref
possible_keys: INDEX_CREATE
          key: INDEX_CREATE
      key_len: 259
          ref: const
         rows: 1
        Extra: Using where; Using index

最外一层总是PRIMARY。

PRIMARY:表示复杂查询的最外层

DERIVED:用于表示包含在FROM子句中的子查询

UNION:UNION中的第二个或后面的SELECT语句

SUBQUERY:子查询中的SELECT(不在FROM子句中)

table

用于标识查询对应的表,结合id可以看出查询的关联顺序

type

这个属性决定了MySQL如何查找表中的行,也是索引优化的中应该关注的最重要的属性。从差到优,依次为:

all

代表全表扫描,通常是最差的情况

index

按索引次序读取表中数据,最差的情况是按索引的次序读取整个表的数据,这样读取的开销会相当大,因为此时是按照随机的次序去取表中的数据,甚至于比全表扫描效率还低。

range

范围扫描,即有限制的INDEX扫描,通常是带有范围搜索条件时出现。

在通常情况下,优化器会在索引存在的情况下,通过符合 RANGE 范围的条数和总数的比例来选择是使用索引还是进行全表遍历。当需要读取的数据超过一个临界值时,优化器会放弃从索引中读取而改为进行全表扫描,这是为了避免过多的 random disk。

所以有时候会看到使用范围查询时,即使在该字段上建有索引,其type却是ALL的原因。

ref

索引查找,返回的是所有匹配某个单值的行,一般而言在优化得当的SQL查询中,其访问方式多为ref。

eq_ref

和ref类似,只有使用唯一索引或使用主键查找才会出现,其效率比ref更高。

const, system

说明MySQL能将查询转换为常量

NULL

MySQL能在优化阶段分解查询语句,执行阶段甚至不用再访问表或索引。

possible_keys

指出本次查询可以使用哪些索引,这一列是在优化过程早期创建的,有些索引对于后续的优化过程是没用的。

key

显示MySQL实际决定使用的索引。如果没有选择索引,键是NULL。

key_len

显示了MySQL在索引里使用的字节数。

ref

显示使用哪个列(或常数)与key一起从表中选择行。

rows

MySQL估计为了找到所需的行而要读取的行数。这个值虽然不是最终要从表里读取数据的行数,但是也能反映出索引对查询条件的覆盖率。

Extra

这里显示了一些重要的额外信息,对于索引优化工作,首先需要关注以下几个额外信息:

Using index

当在Extra列中显示这个信息时,这表明此次查询没有访问表,因为在索引中已经有足够的数据。所以,可以把这个当作”Using index only”。这里有一点需要注意的是,当使用聚集索引时(通常是主键的默认索引),尽管查询只扫描了索引,但在Extra中并不会显示”Using index”。

Using index condition

当出现这个信息时表明,本次查询首先会访问索引进行搜索过滤,然后从索引中得到结果后再进行回表查询。这里使用了push down技术,具体可以参考官方文档: https://dev.mysql.com/doc/refman/5.6/en/index-condition-pushdown-optimization.html