执行计划是什么?
使用 EXPLAIN 关键字可以模拟优化器执行SQL查询语句,从而知道MySQL是 如何处理你的SQL语句的,分析你的查询语句或是表结构的性能瓶颈。
官网介绍: dev.mysql.com/doc/refman/…
前提介绍:文中所有案例 mysql 版本为 5.7.23
执行计划帮助我们完成什么事情?
- 表的读取顺序
- 数据读取操作的操作类型
- 哪些索引可以使用
- 哪些索引被实际使用
- 表之间的引用
- 每张表有多少行被优化器查询
怎么使用执行计划?
- expain + SQL 语句
- 执行计划包含信息
执行计划包含信息解释
id
select 查询的序列号,包含一组数字, 表示查询中执行 select 子句或操作表的顺序
use oemp; #测试表1 CREATE TABLE `t1` ( `id` int(11) NOT NULL AUTO_INCREMENT, `other_column` varchar(30) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8; #测试表2 CREATE TABLE `t2` ( `id` int(11) NOT NULL AUTO_INCREMENT, `other_column` varchar(30) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8; #测试表3 CREATE TABLE `t3` ( `id` int(11) NOT NULL AUTO_INCREMENT, `other_column` varchar(30) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8; #id 相同 explain select t2.* from t1,t2,t3 where t1.id = t2.id and t1.id = t3.id and t3.other_column = ''; #id 不同 explain select t2.* from t2 where id = (select id from t1 where id = (select t3.id from t3 where t3.other_column = '')); #id 相同和不同同时存在 explain select t2.* from (select t3.id from t3 where t3.other_column = '') s1,t2 where s1.id = t2.id;
包含三种情况: id 相同,id 不同,id 相同和 id 不同同时存在。
id 相同
id 相同,执行结果从上而下
- 运行结果
id 不同
id不同如果是自查询,id 的序号会递增,id 值越大,优先级越高,越先被执行
- 运行结果
id 相同和 id 不同时存在
id 如果相同,可以认为是一组的,从上往下执行;在所有组中,id 值越大,优先级越高,越先被执行;衍生 = DERIVED
- 执行结果
derived_merge 是 Mysql5.7 引入的,会试图将 Derived Table (派生表,from 后的自查询) 视图引用,公用表达式(Common table expressions) 与外层查询进行合并。 MySQL 5.7 不在兼容的实现方式,可以通过调整 optimizer_switch 来加以规避
set optimizer_switch='derived_merge=off';
说白了,如果设置为 on 那么就不会出现 derived_merge 行 结果如下:
select_type
包括范围: simple. primary,subquery, derived, union, union result 查询类型主要是用于区别普通查询,联合查询,子查询等复杂的查询
- 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
- 这行数据是关于那种表的
type
类型: all , index , range, ref, eq_ref, const, system ,null type 显示的是防卫类型,是较为重要的一个指标,结果从好到坏依次是:system > count > eq_ref > range > index > all
sytem > const > eq_ref > ref > fulltext > ref_or_null > index_merge >> unique_subquery > index_subquery > range > index > ALL
system
表只有一行记录(等于系统表),这是 const 类型的特列, 平时不会出现,这个也可以忽略不计