Mysql 执行计划
在企业的应用场景中,为了知道优化SQL语句的执行,需要查看SQL语句的具体执行过程,以加快SQL语句的执行效率。
可以使用explain+SQL语句来模拟优化器执行SQL查询语句,从而知道mysql是如何处理sql语句的。
官网地址: https://dev.mysql.com/doc/refman/5.5/en/explain-output.html
执行计划中包含的信息
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 |
- id
select查询的序列号,包含一组数字,表示查询中执行select子句或者操作表的顺序
1.如果id相同,从上到下执行
2.如果id不同,是子查询,id会递增,id越大优先级越高
3.id相同和不同的,相同的是一组,一组中从上往下执行,id越大优先级越高 - select_type
1.sample:简单的查询,不包含子查询和union
explain select * from emp;
2.primary:查询中包含任何负责的子查询,最外层就被标记为primary
explain select staname,ename supname from (select ename staname,mgr from emp) t join emp on t.mgr=emp.empno ;
3.union:第二个select出现在union之后标记为union
explain select * from emp where deptno = 10 union select * from emp where sal >2000;
4.dependent union:和union类似,dependent 表示 union 或 unionAll 的联合结果受外部影响
explain select * from emp e where e.empno in ( select empno from emp where deptno = 10 union select empno from emp where sal >2000);
5.union result:从union获取结果的result
explain select * from emp where deptno = 10 union select * from emp where sal >2000;
6.subquery:在select或where 中包含子查询
explain select * from emp where sal > (select avg(sal) from emp) ;
7.dependent subquery:subquery 的子查询受到外部条件的影响
explain select * from emp e where e.deptno in (select distinct deptno from dept);
8.derived:from后出现子查询中,也叫派生类
explain select staname,ename supname from (select ename staname,mgr from emp) t join emp on t.mgr=emp.empno ;
9.uncacheable subquery:表示使用子查询的结果不能被缓存
explain select * from emp where empno = (select empno from emp where deptno=@@sort_buffer_size);
10.unchchaable union:union 的结果不能被缓存
目前没有sql验证
- table
对应行正在访问哪一个表,表名或者别名,可能是临时表或者union合并结果集 - type
type显示的是访问类型,访问类型表示我是以哪种方式访问我们的数据,最直接是All,扫描全表,效率最低。访问类型有很多,效率从最好到最坏依次是:
system -> const -> eq_ref -> ref -> fulltext -> ref_or_null -> index_merge -> unique_subquery -> index_subquery -> range ->index -> All
一般情况下,要保证查询达到range级别,最好达到ref级别。
1.All
全表扫描,出现这个,数据量比较大的情况下,需要优化
explain select * from emp;
2.index
全索引扫描,效率比All好。两种情况:1.使用了覆盖索引。2.使用了索引排序
explain select empno from emp;
3.range
表示利用索引查询限制了范围,在指定范围内查询
explain select * from emp where empno between 7000 and 7500;
4.index_subquery
利用索引来关联子查询,不再扫描全表
explain select * from emp where emp.job in (select job from t_job);
5.unique_subquery
和index_subquery类似,使用的是唯一索引
explain select * from emp e where e.deptno in (select distinct deptno from dept);
6.index_merge
查询中使用多个索引组合使用
7.ref_or_null
对某个索引需要关联查询,也需要null值的条件
explain select * from emp e where e.mgr is null or e.mgr=7369;
8.ref
使用了非唯一性索引进行数据查找
create index idx_3 on emp(deptno);
explain select * from emp e,dept d where e.deptno =d.deptno;
9.eq_ref
使用了唯一性索引进行数据查找
explain select * from emp,emp2 where emp.empno = emp2.empno;
10.const
表里至多有一行匹配
11.system
表只有一行记录,等于系统表 - possible_keys
显示可能应用在这张表中的索引,一个或多个,查询的字段如果涉及到索引,都会被列出,但不一定被使用 - key
实际使用到的索引,如果为null,则没有使用索引,查询中如果使用了覆盖索引,该字段和查询的select字段重叠 - key_len
索引中使用的字节数长度,不损失精度的情况下,长度越短越好 - ref
显示索引的哪一列被使用到。 - rows
根据表的统计信息和使用情况,估算出索引扫描的行数,此参数很重要,反应了sql扫描了多少行,越少越好 - extra
额外信息
--using filesort:说明mysql无法利用索引进行排序,只能利用排序算法进行排序,会消耗额外的位置
explain select * from emp order by sal;
--using temporary:建立临时表来保存中间结果,查询完成之后把临时表删除
explain select ename,count(*) from emp where deptno = 10 group by ename;
--using index:这个表示当前的查询时覆盖索引的,直接从索引中读取数据,而不用访问数据表。如果同时出现using where 表名索引被用来执行索引键值的查找,如果没有,表面索引被用来读取数据,而不是真的查找
explain select deptno,count(*) from emp group by deptno limit 10;
--using where:使用where进行条件过滤
explain select * from t_user where id = 1;
--using join buffer:使用连接缓存,情况没有模拟出来
--impossible where:where语句的结果总是false
explain select * from emp where empno = 7469;