MySQL执行计划命令EXPLAIN详解


MySQL执行计划命令EXPLAIN详解

文章插图
 
前言我们在写服务端代码时 , 经常会与SQL语句打交道 , 最初写SQL时主要注重的是能不能正常执行SQL , 然后查询出的数据是否正常 。如果这两方面没有问题 , 基本不会考虑SQL执行速度的问题 , 毕竟这个时候数据库中数据量还是很少的 , 怎么写都执行都很快 。但是随着数据量的增加 , 会发现系统查询速度越来越慢 , 这时就需要对系统进行优化了 。
最初优化的方向就是是否存在慢查询 , 如果存在我们应该怎么去优化这些SQL语句 , 今天我们就介绍一下日常中经常使用的EXPLAIN命令 。
EXPLAIN命令简介EXPLAIN命令可以模拟优化器执行SQL查询语句 , 从而知道MySQL是如何处理你的SQL语句的 。分析你的查询语句或是表结构的性能瓶颈 。
通过EXPLAIN我们可以分析出一下几个结果:
  1. 表的读取顺序;
  2. 数据读取操作的操作类型;
  3. 哪些索引可以使用;
  4. 哪些索引被实际使用;
  5. 表之间的引用;
  6. 每张表有多少行被优化器查询
EXPLAIN的使用方式:EXPLAIN + SQL语句 , 例如:
EXPLAIN SELECT * FROM t1执行结果包含的信息 , 如下图:
MySQL执行计划命令EXPLAIN详解

文章插图
 
执行计划返回有10个字段 , 分别是:id、select_type、table、type、possible_keys、key、key_len、ref、rows、Extra , 下面我们就具体分析执行结果中返回的每个字段的具体含义 。
EXPLAIN执行计划字段含义详解ID字段
ID字段是SELECT查询的序列号 , 表示查询中执行select子句或操作表的顺序;
ID字段大概可以出现3中不同的情况:
1、ID字段数值都相同 , 如下图:
MySQL执行计划命令EXPLAIN详解

文章插图
 
此时所有的ID字段数值都相同 , SQL语句执行顺序由上到下 , 顺序执行 。SQL中不存在子查询等 , 如下SQL:
SELECT * FROM a , b WHERE a.id = b.id2、ID字段数值按递增顺序出现 , 如下图:
MySQL执行计划命令EXPLAIN详解

文章插图
 
此时ID字段的数值是递增出现的 , ID数值越大优先级就越高 , SQL语句就优先执行 , 对应的SQL语句如下:
SELECT * FROM a WHERE a.id = (SELECT id FROM b WHERE b.id = (SELECT id FROM c where c.sub_id = 1))子查询级别越深 , ID的数值就越大 , 也就优先执行 。
3、ID字段中相同数值和不相同数值同时存在 , 如下图:
MySQL执行计划命令EXPLAIN详解

文章插图
 
此时ID数值相同的算作一组 , 级别相同按顺序执行 , ID数值越高的级别越高 , 越先执行 。
注意:衍生出来的表定义为DERIVED , 有多个时会在“DERIVED”后加入一个数字标识区分 。
此种情况对应的SQL , 如下:
SELECT *FROM ( SELECT a.id,a.sub FROM a) b INNER JOIN c ON c.id = b.idselect_type字段
select_type字段主要用来区分查询的类型 , 如普通查询、联合查询、子查询等类型 , 具体可以分为以下几种类型:
  • SIMPLE 简单的select查询 , 查询中不包含子查询或者UNION;
  • PRIMARY 查询中若包含任何复杂的子部分 , 最外层查询则被标记为PRIMARY;
  • SUBQUERY 在SELECT或WHERE列表中包含了子查询;
  • DERIVED 在FROM列表中包含的子查询被标记为DERIVED(衍生) , MySQL会递归执行这些子查询 , 把结果放在临时表中;
  • UNION 若第二个SELECT出现在UNION之后 , 则被标记为UNION:若UNION包含在FROM子句的子查询中 , 外层SELECT将被标记为:DERIVED;
  • UNION RESULT 从UNION表获取结果的SELECT
table字段
table字段指的是当前执行的表
type字段
type字段是比较重要的 , 平常我们进行优化时主要关注的也是这个字段 , 这个字段表示的是我们在查询时访问表的方式 , 大概分ALL、index、range、 ref、eq_ref、const、system、NULL(从左到右 , 性能从差到好 。一般来说 , 得保证查询至少达到range级别 , 最好能达到ref) 。


推荐阅读