explain字段列说明

如果想要MySQL给一些提示的话,可以用explain extended 语句。

id

  1. id的编号是select的序列号,有几个select就有几个id,并且id的顺序是按select出现的顺序增长的,分析的时候,只要按这个id的顺序来对应sql语句的哪个部分就好了。需要注意的是,explian的多行记录,如果是一个select语句里完成的,那么id是一样的,即使id一样,也是按从上到下的顺序解析执行计划。
  2. id为1的,在多表关联的时候是驱动表
  3. 如果没有id的话,代表的是中间的计算结果,例如union result

select_type

查询类型,说明查询的种类,select_type有很多种类型
l6j5c2hm.png

  1. sample,最简单查询,查询不包含子查询和union联合查询,大多数sql都是这个
  2. primary,复杂查询中最外层的select,通常这个是出现在第一行,一看到primary,就知道这肯定是个嵌套循环了,是驱动表
  3. derived,派生查询,包含在from子句中的子查询,mysql会将结果存放在一个临时表中,也称派生表
  4. union,是指向union关键字之后的查询
  5. union result,因为union联合的话,会去重等操作,得到的结果union result,如果是union all操作,因为没有去重等操作,所以就不会有union result,需要注意的是union result越小越好,如果可能的话,最好不要有union result,因为会产生临时表,是没有索引的,对临时表进行操作,速度必然很慢,所以用union的时候要么就是用union all简单关联,要么union结果要很少
  6. subquery,包含在select中的子查询,也就是select关键字之后的查询

table

表示select操作的是哪个表,如果没有表名的话,例如<union 3,4>,表示对前面id编号的数据进行操作

partitions

表示分区表的意思,如果对mysql设置分区的时候,这一列就会显示我们的表落在哪个分区上

type

这一列表示关联类型或者访问类型,即mysql决定如何查找表中的行,执行效率排序:

  1. system,
  2. const,代表是常量引用,一般主键或者唯一列筛选,因为只有一行,与参数进行比较,所以比较快
  3. eq_ref,用于关联查询,两个表进行关联查询的时候,通过主键或者唯一值列,和另外一张表的外键进行连接
  4. ref,用于非主键,或者非唯一性索引的检索
  5. fulltext,用的很少
  6. ref_or_null,包含null情况的索引检索
  7. index_merge
  8. unique_subquery,
  9. index_subquery
  10. range,范围检索,通常出现在in,between,>,<,>=,like等操作中,使用一个索引来检索给的范围的行。
  11. index,通过索引做的全表扫描
  12. All,代表存储的全表扫描

possible_keys

这一列显示查询可能使用哪些索引来查找

key

显示最终使用哪个索引来优化,从possible_keys中选的索引。

key_len

这一列显示了mysql在索引里使用的字节数,通过这个值,可以算出具体使用了索引中的那些列,例如索引是int类型,int类型是4个字节,那么Key_len等于4

ref

这一列显示了,在key列记录的索引中,表查找值所用到的列或常量,常见的有:const(常量),func,NULL,字段名(例如:film.id)

rows

这一列是mysql explain 记录里,该行估计要读取并检测的行数,注意这个不是结果集里的行数

filtered

代表过滤的意思,是百分比的值,(rows*filtered)/100,这个计算结果表示最终可能的结果,这个结果将于explain结果的上一行对应表产生交互,比如合并交互

Extra

扩展列,用于展示一些额外信息,例如distinc,表示mysql一旦找到了与行相匹配的行,就不再搜索了。

  1. using index,也叫索引覆盖,不会去原始数据中查找数据行,直接返回索引上的值
  2. using where,先读取整行数据,然后再利用where条件进行检查,符合就留下,不符合就丢弃,出现这个表示数据访问效率不是很高
  3. using temporary,表示使用临时表,临时表在内存中计算很慢,如果出现这个,就要进行优化了
  4. using filesort,表示采用文件扫描对结果进行计算排序,效率很低。对于排序,只有select的所有字段和order by字段都被索引覆盖时候,就会使用using index.
    -- 假设索引是idx_name_ut(name,update_time),这样就可以using index了
    select name,update_time from actor order by name;
    -- 因为order by 的顺序和索引的顺序不一样,所以name用不到索引,会file sort
    select name,update_time from actor order by update_time,name;
最后修改:2023 年 12 月 30 日
如果觉得我的文章对你有用,请随意赞赏