Explain性能分析


1、explain的基本介绍

有时候我们可能需要知道 mysql 是如何解析执行我们的 SQL 语句的,比如有时候某些语句写在前面并不一定意味着它就会先执行,有没有使用到索引等待,此时我们可以通过 explain 语句来分析出 SQL 优化器是如何解析执行我们的 SQL 语句的。

使用 EXPLAIN 关键字可以模拟优化器执行 SQL 查询语句,从而知道 MySQL 是如何处理你的 SQL 语句的,explain 主要用于分析查询语句或表结构的性能瓶颈。

1.1、explain的作用

通过explain+sql语句可以知道如下内容:

  1. 表的读取顺序(对应id)。
  2. 数据读取操作的操作类型(对应select_type)。
  3. 哪些索引可以使用(对应possible_keys)。
  4. 哪些索引被实际使用(对应key)。
  5. 表直接的引用(对应ref)。
  6. 每张表有多少行被优化器查询(对应rows)。

2、explain的基本使用

使用 explain 关键字来分析 SQL 语句的性能,只需要在 SQL 语句的前面加上 explain 即可,语法如下:

explain sql语句;
-- 示例
explain select * from tbl_emp,tbl_dept where tbl_emp.deptId = tbl_dept.id;

执行结果:

3、explain的字段意思

使用 expain 分析 SQL 性能时,列出来的信息有10列,分别是id、select_type、table、type、possible_keys、key、key_len、ref、rows、Extra。

概要描述:

  • id:表的读取顺序
  • select_type:数据读取操作的操作类型。
  • table:该查询是基于哪张表的
  • partitions:匹配的分区
  • type:表示表的连接类型
  • possible_keys:哪些索引可以使用
  • key:哪些索引被实际使用
  • key_len:索引字段的长度
  • ref:表直接的引用
  • rows:扫描出的行数(估算的行数)
  • filtered:按表条件过滤的行百分比
  • Extra:执行情况的描述和说明

3.1、id(表的读取顺序)

explain 分析出来的 id 字段表示查询中执行 select 子句或操作表的顺序。比如,当查询的 SQL 语句涉及到多个表时,explain 分析出来的数据就有多条,其中 id 值越大的,表示SQL优化器会越早执行这个表。

其中,有三种情况:id全部相同、id全部不同、id部分相同。

3.1.1、id全部相同(执行顺序由上至下)

比如我们执行 explain 来分析某条SQL语句,其中涉及到三个表。如下图:

可以看到结果中,id全部都相同,此时意味着 SQL 优化器的执行顺序为由上至下。也就是 SQL 优化器实际上的执行计划是:先执行 t1 表的查询,再执行 t3 表,最后执行 t2 表。

3.1.2、id全部不同(id越大,越先被执行)

比如我们执行 explain 来分析某条SQL语句,其中涉及到三个表。如下图:

可以看到结果中,id全部不同,id 值越大优先级越高,越先被执行。也就是 SQL 优化器实际上的执行计划是:先执行 t3 表的查询,再执行 t2 表,最后执行 t1 表。

一般当涉及到子查询时,id 的序号会递增,id 值越大优先级越高,越先被执行.

3.1.3、id部分相同(相同id由上至下执行)

比如我们执行 explain 来分析某条SQL语句,其中涉及到三个表。如下图:

可以看到结果中,id部分相同,部分不同,此时仍然适用 id 值越大越先被执行的原则,id 相同的可以认为是同一组,从上往下顺序执行。也就是 SQL 优化器实际上的执行计划是:先执行 t3 表的查询,再执行衍生表 derived2,最后执行 t2 表。

(衍生表 derived2 的意思是该衍生表是 id 为2,即 t3 表的虚拟表)

3.2、select_type(查询操作的类型)

select_type 代表查询的类型,主要是用于区别普通查询、联合查询、子查询等的复杂查询。

select_type 的值和含义如下:

  • SIMPLE:简单的 select 查询,查询中不包含子查询或者 UNION。

  • PRIMARY:查询中若包含任何复杂的子部分,最外层查询则被标记为 Primary。

  • DERIVED:在 FROM 列表中包含的子查询被标记为 DERIVED(衍生) MySQL 会递归执行这些子查询,,把结果放在临时表里。
  • SUBQUERY:在SELECT或WHERE列表中包含了子查询。

  • DEPEDENT SUBQUERY:在SELECT或WHERE列表中包含了子查询,子查询基于外层。

 都是 where 后面的条件,subquery 是单个值,dependent subquery 是一组值。

  • UNCACHEABLE SUBQUERY:无法使用缓存的子查询。

 当使用了@@来引用系统变量的时候,不会使用缓存。

  • UNION:若第二个SELECT出现在UNION之后,则被标记为UNION; 若UNION包含在FROM子句的子查询中,外层SELECT将被标记为:DERIVED。

  • UNION RESULT:从UNION表获取结果的SELECT。