Mysql

关注公众号 jb51net

关闭
首页 > 数据库 > Mysql > Mysql Explain执行计划

Mysql深入探索之Explain执行计划详析

作者:不才陈某

这篇文章主要给大家介绍了关于Mysql深入探索之Explain执行计划的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

前言

如何写出效率高的SQL语句,提到这必然离不开Explain执行计划的分析,至于什么是执行计划,如何写出高效率的SQL,本篇文章将会一一介绍。

执行计划

执行计划是数据库根据 SQL 语句和相关表的统计信息作出的一个查询方案,这个方案是由查询优化器自动分析产生的。

使用explain关键字可以模拟优化器执行 SQL 查询语句,从而知道 MySQL 是如何处理你的 SQL 语句的,分析你的 select 语句或是表结构的性能瓶颈,让我们知道 select 效率低下的原因,从而改进我们的查询。

explain 的结果如下:

下面是有关各列的详细介绍,重要的有id、type、key、rows、extra。

id

select_type

查询的类型,主要用于区分普通查询、联合查询、子查询等复杂的查询;

simple:表示查询中不包括 union 操作或者子查询,位于最外层的查询的 select_type 即为 simple,且只有一个;

 explain select * from t3 where id=3952602;

primary:需要 union 操作或者含有子查询的 select,位于最外层的查询的 select_type 即为 primary,且只有一个;

explain select * from (select * from t3 where id=3952602) a ;

derived:from 列表中出现的子查询,也叫做衍生表;mysql 或者递归执行这些子查询,把结果放在临时表里。

 explain select * from (select * from t3 where id=3952602) a ;

subquery:除了 from 子句中包含的子查询外,其他地方出现的子查询都可能是 subquery。

explain select * from t3 where id = (select id from t3 whereid=3952602 ) ;

union:若第二个 select 出现在 union 之后,则被标记为 union;若 union 包含在 from 子句的子查询中,外层 select 将被标记为 derived。

explain select * from t3 where id=3952602 union all select * from t3;

union result:从 union 表获取结果的 select ,因为它不需要参与查询,所以 id 字段为 null。

 explain select * from t3 where id=3952602 union all select * from t3;

dependent union:与 union 一样,出现在 union 或 union all 语句中,但是这个查询要受到外部查询的影响;

dependent subquery:与 dependent union 类似,子查询中的第一个 SELECT,这个 subquery 的查询要受到外部表查询的影响。

table

表示 explain 的一行正在访问哪个表。

type

访问类型,即 MySQL 决定如何查找表中的行。

依次从好到差:system > const > eq_ref > ref > fulltext > ref_or_null > index_merge > unique_subquery > index_subquery > range > index > ALL,除了 all 之外,其他的 type 都可以使用到索引,除了 index_merge 之外,其他的 type 只可以用到一个索引。一般来说,得保证查询至少达到 range 级别,最好能达到 ref。

  1. system:表中只有一行数据(等于系统表),这是 const 类型的特例,平时不会出现,可以忽略不计。
  2. const:使用唯一索引或者主键,表示通过索引一次就找到了,const 用于比较 primary key 或者 unique 索引。因为只需匹配一行数据,所有很快。如果将主键置于 where 列表中,mysql 就能将该查询转换为一个 const。
  3. eq_ref:唯一性索引扫描,对于每个索引键,表中只有一行数据与之匹配。常见于主键或唯一索引扫描。
  4. ref:非唯一性索引扫描,返回匹配某个单独值的所有行。本质也是一种索引。
  5. fulltext:全文索引检索,全文索引的优先级很高,若全文索引和普通索引同时存在时,mysql 不管代价,优先选择使用全文索引。
  6. ref_or_null:与 ref 方法类似,只是增加了 null 值的比较。
  7. index_merge:表示查询使用了两个以上的索引,索引合并的优化方法,最后取交集或者并集,常见 and ,or 的条件使用了不同的索引。
  8. unique_subquery:用于 where 中的 in 形式子查询,子查询返回不重复值唯一值;
  9. index_subquery:用于 in 形式子查询使用到了辅助索引或者 in 常数列表,子查询可能返回重复值,可以使用索引将子查询去重。
  10. range:索引范围扫描,常见于使用>,<,between ,in ,like等运算符的查询中。
  11. index:索引全表扫描,把索引树从头到尾扫一遍;
  12. all:遍历全表以找到匹配的行(Index 与 ALL 虽然都是读全表,但 index 是从索引中读取,而 ALL 是从硬盘读取)
  13. NULL: MySQL 在优化过程中分解语句,执行时甚至不用访问表或索引。

possible_keys

显示查询可能使用到的索引。

key

显示查询实际使用哪个索引来优化对该表的访问;

select_type 为 index_merge 时,这里可能出现两个以上的索引,其他的 select_type 这里只会出现一个。

key_len

ref

显示哪个字段或者常数与 key 一起被使用。

rows

表示 MySQL 根据表统计信息及索引选用情况,大致估算的找到所需的目标记录所需要读取的行数,不是精确值。

extra

不适合在其他列中显示但十分重要的额外信息。

这个列可以显示的信息非常多,有几十种,常用的有:

类型 说明
Using filesort MySQL 有两种方式可以生成有序的结果,通过排序操作或者使用索引,当 Extra 中出现了 Using filesort 说明 MySQL 使用了后者,但注意虽然叫 filesort 但并不是说明就是用了文件来进行排序,只要可能排序都是在内存里完成的。大部分情况下利用索引排序更快,所以一般这时也要考虑优化查询了。使用文件完成排序操作,这是可能是 ordery by,group by 语句的结果,这可能是一个 CPU 密集型的过程,可以通过选择合适的索引来改进性能,用索引来为查询结果排序。
Using temporary 用临时表保存中间结果,常用于 GROUP BY 和 ORDER BY 操作中,一般看到它说明查询需要优化了,就算避免不了临时表的使用也要尽量避免硬盘临时表的使用。
Not exists MYSQL 优化了 LEFT JOIN,一旦它找到了匹配 LEFT JOIN 标准的行, 就不再搜索了。
Using index 说明查询是覆盖了索引的,不需要读取数据文件,从索引树(索引文件)中即可获得信息。如果同时出现 using where,表明索引被用来执行索引键值的查找,没有 using where,表明索引用来读取数据而非执行查找动作。这是 MySQL 服务层完成的,但无需再回表查询记录。
Using index condition 这是 MySQL 5.6 出来的新特性,叫做“索引条件推送”。简单说一点就是 MySQL 原来在索引上是不能执行如 like 这样的操作的,但是现在可以了,这样减少了不必要的 IO 操作,但是只能用在二级索引上。
Using where 使用了 WHERE 从句来限制哪些行将与下一张表匹配或者是返回给用户。注意:Extra 列出现 Using where 表示 MySQL 服务器将存储引擎返回服务层以后再应用 WHERE 条件过滤。
Using join buffer 使用了连接缓存:Block Nested Loop,连接算法是块嵌套循环连接;Batched Key Access,连接算法是批量索引连接
impossible where where 子句的值总是 false,不能用来获取任何元组
select tables optimized away 在没有 GROUP BY 子句的情况下,基于索引优化 MIN/MAX 操作,或者对于 MyISAM 存储引擎优化 COUNT(*)操作,不必等到执行阶段再进行计算,查询执行计划生成的阶段即完成优化。
distinct 优化 distinct 操作,在找到第一匹配的元组后即停止找同样值的动作

filtered

关于 MySQL 执行计划的局限性

  1. EXPLAIN 不会告诉你关于触发器、存储过程的信息或用户自定义函数对查询的影响情况;
  2. EXPLAIN 不考虑各种 Cache;
  3. EXPLAIN 不能显示 MySQL 在执行查询时所作的优化工作;
  4. 部分统计信息是估算的,并非精确值;
  5. EXPALIN 只能解释 SELECT 操作,其他操作要重写为 SELECT 后查看。

查询计划案例分析

执行顺序

  1. (id = 4):【select id, name from t2】:select_type 为 union,说明 id=4 的 select 是 union 里面的第二个 select。
  2. (id = 3):【select id, name from t1 where address = ‘11'】:因为是在 from 语句中包含的子查询所以被标记为 DERIVED(衍生),where address = ‘11' 通过复合索引 idx_name_email_address 就能检索到,所以 type 为 index。
  3. (id = 2):【select id from t3】:因为是在 select 中包含的子查询所以被标记为 SUBQUERY。
  4. (id = 1):【select d1.name, … d2 from … d1】:select_type 为 PRIMARY 表示该查询为最外层查询,table 列被标记为 “derived3”表示查询结果来自于一个衍生表(id = 3 的 select 结果)。
  5. (id = NULL):【 … union … 】:代表从 union 的临时表中读取行的阶段,table 列的 “union 1, 4”表示用 id=1 和 id=4 的 select 结果进行 union 操作。

总结

到此这篇关于Mysql深入探索之Explain执行计划的文章就介绍到这了,更多相关Mysql Explain执行计划内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文