mysql 查询计划 | idouba

mysql 查询计划

?

一、 概述

MySQL的查询执行计划(QEP)是借助EXPLAIN命令来实现的。了解MySQL 优化器是如何执行SQL 语句的。只是提供信息并不提供建议。EXPLAIN语句可以用作DESCRIBE的一个同义词,或获得关于MySQL如何执行SELECT语句的信息:?EXPLAIN?tbl_name是DESCRIBE?tbl_name或SHOW COLUMNS FROM?tbl_name的一个同义词。?如果在SELECT语句前放上关键词EXPLAIN,MySQL将解释它如何处理SELECT(在MySQL 5.7, 可以被EXPLAIN?的语句除了SELECT?还有?DELETE,?INSERT,?REPLACE, andUPDATE),提供有关表如何联接和联接的次序。只关心语句而不是一个表的explain。

语法:

重点说明下:EXPLAIN EXTENDED将执行计划“反编译”成SELECT语句,运行SHOW WARNINGS 可得到被MySQL优化器优化后的查询语句

输出

Column Meaning
id The?SELECT?identifier
select_type The?SELECT?type
table The table for the output row
partitions The matching partitions
type The join type
possible_keys The possible indexes to choose
key The index actually chosen
key_len The length of the chosen key
ref The columns compared to the index
rows Estimate of rows to be examined
filtered Percentage of rows filtered by table condition
Extra Additional information

?二、执行计划输出详细

1. ??ID:Query Optimizer 所选定的执行计划中查询的序列号;?包含一组数字,表示查询中执行select子句或操作表的顺序?。id值越大优先级越高,越先被执行;id相同,则从上往下顺序执行。一般对于select * from t1, t2, t3 where 这样的查询,id相同;而子查询,id的序号会递增。

2. ?select_type:所使用的查询类型

select_typeValue Meaning
SIMPLE Simple?SELECT?(not using?UNION?or subqueries)
PRIMARY Outermost?SELECT
UNION Second or later?SELECT?statement in a?UNION
DEPENDENT UNION Second or later?SELECT?statement in a?UNION, dependent on outer query
UNION RESULT Result of a?UNION.
SUBQUERY First?SELECT?in subquery
DEPENDENT SUBQUERY First?SELECT?in subquery, dependent on outer query
DERIVED Derived table?SELECT?(subquery in?FROM?clause)
MATERIALIZED Materialized subquery
UNCACHEABLE SUBQUERY A subquery for which the result cannot be cached and must be re-evaluated for each row of the outer query
UNCACHEABLE UNION The second or later select in a?UNION?that belongs to an uncacheable subquery (seeUNCACHEABLE SUBQUERY)

详细解释如下,比较常见的simple、primary、subquery、derived、union等都是根据基本的sql基础很好理解的。

  • SIMPLE:查询中不包含子查询或者UNION
  • 查询中若包含任何复杂的子部分,最外层查询则被标记为:PRIMARY
  • 在SELECT或WHERE列表中包含了子查询,该子查询被标记为,结果不依赖于外部查询结果集:SUBQUERY
  • 在FROM列表中包含的子查询被标记为:DERIVED(衍生)
  • 若第二个SELECT出现在UNION之后,则被标记为UNION;若UNION包含在? FROM子句的子查询中,外层SELECT将被标记为:DERIVED。第一个SELECT 为PRIMARY
  • 从UNION表获取结果的SELECT被标记为:UNION RESULT
  • ?DEPENDENT SUBQUERY:子查询中内层的第一个SELECT,依赖于外部查询的结果集;
  • ?DEPENDENT UNION:子查询中的UNION,且为UNION 中从第二个SELECT 开始的后面所有SELECT,同样依赖于外部查询的结果集;

3.?Table:显示这一步所访问的数据库中的表的名称

4. ?type

  • ?all:全表扫描
  • ?const:读常量,且最多只会有一条记录匹配,(const?is used when you compare all parts of a?PRIMARY KEY?or?UNIQUE?index to constant values. In the following queries,?tbl_name?can be used as a?const?table);

  • ?fulltext:
  • ?index:全索引扫描(The?index?join type is the same as?ALL,except that the index tree is scanned);
  • ?index_merge:查询中同时使用两个(或更多)索引,然后对索引结果进行merge 之后再读取表数据(This join type indicates that the Index Merge optimization is used. In this case, the?key?column in the output row contains a list of indexes used, and?key_len?contains a list of the longest key parts for the indexes used);
  • ?index_subquery:子查询中的返回结果字段组合是一个索引(或索引组合),但不是一个主键或者唯一索引;
  • ?rang:索引范围扫描;
  • ?ref:Join 语句中被驱动表索引引用查询(ref?can be used for indexed columns that are compared using the?=?or?<=>?operator);

  • eq_ref:最多只会有一条匹配结果,一般是通过主键或者唯一键索引来访问(?eq_refis used when all parts of an index are used by the join and the index is a?PRIMARY KEY?or?UNIQUE NOT NULL?index);

  • ?ref_or_null:与ref 的唯一区别就是在使用索引引用查询之外再增加一个空值的查询;

我的注释: ref、eq_ref、ref_or_null 都是join语句中被驱动表的索引语句查询,只是eq_ref要求的链接条件必须是主键活唯一索引,匹配一条记录;而ref_or_null在使用索引引用之外可以空值。

  • ?system:系统表,表中只有一行数据;
  • ?unique_subquery:子查询中的返回结果字段组合是主键或者唯一约束;

4. ?Possible_keys:

该查询可以利用的索引. 如果没有任何索引可以使用,就会显示成null,这一项内容对于优化时候索引的调整非常重要;

?5.??Key:

MySQL Query Optimizer 从possible_keys 中所选择使用的索引;但很少的情况选择的Key不在Possible_key中出现。For?InnoDB, a secondary index might cover the selected columns even if the query also selects the primary key because?InnoDB?stores the primary key value with each secondary index. If?key?is?NULL, MySQL found no index to use for executing the query more efficiently.

6. ?Key_len:

被选中使用索引的索引键长度;

? 7. Ref:

列出是通过常量(const)或者某个表的某个字段(如果是join)来过滤(通过key)的;(The?ref?column shows which columns or constants are compared to the index named in the?key?column to select rows from the table.)即关联的那一列的取值,对于某个where key = 123的是const,如果是where a.column1 = b.column2, 则列出关联的列名。

8.?Rows

MySQL Query Optimizer 通过系统收集到的统计信息估算出来的结果集记录条数;

?9.?Extra

每一步查询的额外信息。常用的列举出来。

  • Using filesort:当Query 中包含ORDER BY 操作,而且无法利用索引完成排序操作的时候,Query Optimizer 不得不选择相应的排序算法来实现。
  • Using index:所需要的数据只需要在Index 即可全部获得而不需要再到表中取数据;
  • Using index for group-by:数据访问和Using index 一样,所需数据只需要读取索引即可,而当Query 中使用了GROUP BY 或者DISTINCT 子句的时候,如果分组字段也在索引中,Extra 中的信息就会是Using index for group-by;
  • Using temporary:当MySQL 在某些操作中必须使用临时表的时候,在Extra 信息中就会出现Using temporary 。主要常见于GROUP BY 和ORDER BY 等操作中。
  • Distinct:查找distinct 值,所以当mysql 找到了第一条匹配的结果后,将停止该值的查询而转为后面其他值的查询;
  • No tables:Query 语句中使用FROM DUAL 或者不包含任何FROM 子句;
  • Not exists:在某些左连接中MySQL Query Optimizer 所通过改变原有Query 的组成而使用的优化方法,可以部分减少数据访问次数;
  • Select tables optimized away:当我们使用某些聚合函数来访问存在索引的某个字段的时候,MySQL Query Optimizer 会通过索引而直接一次定位到所需的数据行完成整个查询。当然,前提是在Query 中不能有GROUP BY 操作。如使用MIN()或者MAX()的时候;
  • Using where:如果不是读取表的所有数据,或者不是仅仅通过索引就可以获取所有需要的数据,则会出现Using where 信息.

三、参考:

explain 语法

mysql explain

原创文章。为了维护文章的版本一致、最新、可追溯,转载请注明: 转载自idouba

本文链接地址: mysql 查询计划


, ,

No comments yet.

发表评论