官方文档:https://dev.mysql.com/doc/refman/5.7/en/explain-output.html
[toc]
explain mysql 的查询语句会有如下的结果:
eg1:
eg2:
eg3:
eg4:
eg5:
(一)id:
select 查询的序列号,如果id相同,则按照自上向下的顺序执行,如果包含有子查询,id会自增,序号越大优先级越高,越先执行
(二)select_type:查询类型
1. SIMPLE:简单的查询,没有子查询和UNION
2. PRIMARY: 如果有复杂查询的话,标记最外层的查询为primary
3. UNION:例如eg2中的谓语UNION关键字后面的查询就select_type标记为UNION
4. DEPENDENT UNION:UNION中的第二个或后面的SELECT语句,取决于外面的查询
5. UNION RESULT:UNION的结果
6. SUBQUERY:子查询中的第一个SELECT
7. DEPENDENT SUBQUERY:子查询中的第一个SELECT,取决于外面的查询
8. DERIVED:派生的表 ,例如eg3
9. MATERIALIZED:具体化的子查询,例如eg4
10. UNCACHEABLE SUBQUERY :子查询的结果不能被缓存,必须重新评估为每一行的外部查询
11. UNCACHEABLE UNION:UNION中的第二个或后面的SELECT语句,而且不能被缓存
(三)table:
关于数据是哪张表的,有几个比较特殊例如
eg3:table是deriver2,表示这个表的数据是id为2的派生表的数据;
eg4中:table可以是subquery2,表示这个表的数据是id为2的子查询的数据;
eg5:表示这个表的数据是UNION 了id为2,3,4 的子查询的数据
(四)partitions:
数据从哪个分区中匹配数据 。对于非分区表,该值为null。
(五)type:
连接使用哪些类别,有无使用索引;值从好到坏依次如下
1. system:表里面只有一条数据,是const的一种特殊情况
2. const:表中至多有一条数据符合。优化器将这一行中列当作常量来处理,因为只读一次,所以速度非常快。常见:primary key 或者unique index
3. eq_ref:索引扫描只读取一行数据,常用于primary key或者唯一为空(unique not null index)
SELECT * FROM ref_table,other_table WHERE ref_table.key_column=other_table.column;
SELECT * FROM ref_table,other_table WHERE ref_table.key_column_part1=other_table.column AND ef_table.key_column_part2=1;
4. ref:索引扫描返回多行数据,非唯一索引查找。
SELECT * FROM ref_table WHERE key_column=expr;
SELECT * FROM ref_table,other_table WHERE ref_table.key_column=other_table.column;
SELECT * FROM ref_table,other_table WHERE ref_table.key_column_part1=other_table.column AND ref_table.key_column_part2=1;
5. fulltext:使用fulltext index
6. ref_or_null:类似于ref,会额外搜索包含NULL的行,常用于解析子查询
eg:SELECT * FROM ref_table WHERE key_column=expr OR key_column IS NULL
7. index_merge:使用了索引合并优化,在输出key列上包含有多个index.
8. unique_subquery:value IN (SELECT primary_key FROM single_table WHERE some_expr)
9. index_subquery:value IN (SELECT key_column FROM single_table WHERE some_expr)
10. range:检索给定范围的行,并使用index来选择行,例如 =, <>, >, >=, <, <=, IS NULL, <=>, BETWEEN, LIKE, or IN()
11. index:扫描整个index tree,与all 的区别就是all是全表扫描,index是full index 扫描
12. all:全表扫描,实际使用中,如果数据量比较大,应该避免进行全表扫描,因为这种连接是最慢的
(六)possible_keys:
mysql选择查找行数可能会使用的indexs,列举出的index 可能在实际执行中不会使用的
(七)key:
mysql在实际执行查询中使用的index,如果没有使用,则为NULL
(八)key_len:
(七)中key的长度,如果(7)中key为NULL,那么这个也为NULL例如eg1
(九)ref:
表示为了筛选数据,表中哪些列和常量与index进行对比;如果是函数,则比较的是函数的值而不是表达式
(十)rows:
表示mysql执行查询必须检查的行数,InnoDB对于这个数是个预估值,不是准确值。
(十一)filtered:
根据查询条件,过滤后数据所占表的数据的百分比。最大值为100.00表示没有任何过滤如eg1;
eg4中的id为1 表示过滤后数据所占百分比为47%,如果总行数为500条,那么筛选后行数为500*47%=235条。
(十二)extra:这列mysql怎么处理这个查询的(注:如果出现这两种情况Using filesort 或者Using temporary,为了查询性能,尽量避免文件排序或者使用临时表)。以下是常出现的一些类型
1. using fileSort:使用额外操作来进行排序。(注意:1、排序针对的是order by后面跟的列;2、根据排序后的列,顺序的检索每一行)
2. using temporary:使用临时表来存储结果,常出现去group by 或者order by (与列存储的顺序不同才会使用临时表)操作
3. using index:在索引树上只使用索引就得到结果,没有根据索引回表来单独查询行。就是覆盖索引查询
4. using index condition:上面的 using index 不需要回表查询,那using index where则需要每条记录都回表查询才得到最后的查询结果
5. using index for group-by:同using index类似,在group by的时候,可以通过一个索引来检索索引树,无须回表查询
6. using where:使用了where子句来过滤整个表的数据,如果使用了索引,那就是索引失效了。
7. Using sort_union(...),Using union(...), Using intersect(...):使用特定的算法来显示扫描索引是如何合并的在使用join
type(index_merge)的时候