共计 5152 个字符,预计需要花费 13 分钟才能阅读完成。
一、mysql 执行打算
在企业的利用场景中,为了晓得优化 SQL 语句的执行,须要查看 SQL 语句的具体执行过程,以放慢 SQL 语句的执行效率。
能够应用 explain+SQL 语句来模仿优化器执行 SQL 查问语句,从而晓得 mysql 是如何解决 sql 语句的。
官网地址:https://dev.mysql.com/doc/ref…
二、执行打算中蕴含的信息
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 |
1、id
select 查问的序列号,蕴含一组数字,示意查问中执行 select 子句或者操作表的程序
id 号分为三种状况:
1、如果 id 雷同,那么执行程序从上到下
explain select * from emp e join dept d on e.deptno = d.deptno join salgrade sg on e.sal between sg.losal and sg.hisal;
2、如果 id 不同,如果是子查问,id 的序号会递增,id 值越大优先级越高,越先被执行
explain select * from emp e where e.deptno in (select d.deptno from dept d where d.dname = 'SALES');
3、id 雷同和不同的,同时存在:雷同的能够认为是一组,从上往下程序执行,在所有组中,id 值越大,优先级越高,越先执行
explain select * from emp e join dept d on e.deptno = d.deptno join salgrade sg on e.sal between sg.losal and sg.hisal where e.deptno in (select d.deptno from dept d where d.dname = 'SALES');
2、select_type
次要用来分辨查问的类型,是一般查问还是联结查问还是子查问
select_type Value |
Meaning |
---|---|
SIMPLE | Simple SELECT (not using UNION or subqueries) |
PRIMARY | Outermost SELECT |
UNION | Second or later SELECT statement in a UNION |
DEPENDENT UNION | Second or later SELECT statement in a UNION, dependent on outer query |
UNION RESULT | Result of a UNION. |
SUBQUERY | First SELECT in subquery |
DEPENDENT SUBQUERY | First SELECT in subquery, dependent on outer query |
DERIVED | Derived table |
UNCACHEABLE SUBQUERY | A subquery for which the result cannot be cached and must be re-evaluated for each row of the outer query |
UNCACHEABLE UNION | The second or later select in a UNION that belongs to an uncacheable subquery (see UNCACHEABLE SUBQUERY) |
--sample: 简略的查问,不蕴含子查问和 union
explain select * from emp;
--primary: 查问中若蕴含任何简单的子查问,最外层查问则被标记为 Primary
explain select staname,ename supname from (select ename staname,mgr from emp) t join emp on t.mgr=emp.empno ;
--union: 若第二个 select 呈现在 union 之后,则被标记为 union
explain select * from emp where deptno = 10 union select * from emp where sal >2000;
--dependent union: 跟 union 相似,此处的 depentent 示意 union 或 union all 联结而成的后果会受内部表影响
explain select * from emp e where e.empno in (select empno from emp where deptno = 10 union select empno from emp where sal >2000)
--union result: 从 union 表获取后果的 select
explain select * from emp where deptno = 10 union select * from emp where sal >2000;
--subquery: 在 select 或者 where 列表中蕴含子查问
explain select * from emp where sal > (select avg(sal) from emp) ;
--dependent subquery:subquery 的子查问要受到内部表查问的影响
explain select * from emp e where e.deptno in (select distinct deptno from dept);
--DERIVED: from 子句中呈现的子查问,也叫做派生类,explain select staname,ename supname from (select ename staname,mgr from emp) t join emp on t.mgr=emp.empno ;
--UNCACHEABLE SUBQUERY:示意应用子查问的后果不能被缓存
explain select * from emp where empno = (select empno from emp where deptno=@@sort_buffer_size); --uncacheable union: 示意 union 的查问后果不能被缓存:sql 语句未验证
3、table
对应行正在拜访哪一个表,表名或者别名,可能是长期表或者 union 合并后果集
1、如果是具体的表名,则表明从理论的物理表中获取数据,当然也能够是表的别名
2、表名是 derivedN 的模式,示意应用了 id 为 N 的查问产生的衍生表
3、当有 union result 的时候,表名是 union n1,n2 等的模式,n1,n2 示意参加 union 的 id
4、type
type 显示的是拜访类型,拜访类型示意我是以何种形式去拜访咱们的数据,最容易想的是全表扫描,间接暴力的遍历一张表去寻找须要的数据,效率十分低下,拜访的类型有很多,效率从最好到最坏顺次是:
system > const > eq_ref > ref > fulltext > ref_or_null > index_merge > unique_subquery > index_subquery > range > index > ALL
个别状况下,得保障查问至多达到 range 级别,最好能达到 ref
--all: 全表扫描,个别状况下呈现这样的 sql 语句而且数据量比拟大的话那么就须要进行优化。explain select * from emp;
--index:全索引扫描这个比 all 的效率要好,次要有两种状况,一种是以后的查问时笼罩索引,即咱们须要的数据在索引中就能够索取,或者是应用了索引进行排序,这样就防止数据的重排序
explain select empno from emp;
--range:示意利用索引查问的时候限度了范畴,在指定范畴内进行查问,这样防止了 index 的全索引扫描,实用的操作符:=, <>, >, >=, <, <=, IS NULL, BETWEEN, LIKE, or IN() explain select * from emp where empno between 7000 and 7500;
--index_subquery:利用索引来关联子查问,不再扫描全表
explain select * from emp where emp.job in (select job from t_job);
--unique_subquery: 该连贯类型相似与 index_subquery, 应用的是惟一索引
explain select * from emp e where e.deptno in (select distinct deptno from dept); --index_merge:在查问过程中须要多个索引组合应用,没有模仿进去
--ref_or_null:对于某个字段即须要关联条件,也须要 null 值的状况下,查问优化器会抉择这种拜访形式
explain select * from emp e where e.mgr is null or e.mgr=7369;
--ref:应用了非唯一性索引进行数据的查找
create index idx_3 on emp(deptno); explain select * from emp e,dept d where e.deptno =d.deptno;
--eq_ref:应用唯一性索引进行数据查找
explain select * from emp,emp2 where emp.empno = emp2.empno;
--const:这个表至少有一个匹配行,explain select * from emp where empno = 7369;
--system:表只有一行记录(等于零碎表),这是 const 类型的特例,平时不会呈现
5、possible_keys
显示可能利用在这张表中的索引,一个或多个,查问波及到的字段上若存在索引,则该索引将被列出,但不肯定被查问理论应用
explain select * from emp,dept where emp.deptno = dept.deptno and emp.deptno = 10;
6、key
理论应用的索引,如果为 null,则没有应用索引,查问中若应用了笼罩索引,则该索引和查问的 select 字段重叠。
explain select * from emp,dept where emp.deptno = dept.deptno and emp.deptno = 10;
7、key_len
示意索引中应用的字节数,能够通过 key_len 计算查问中应用的索引长度,在不损失精度的状况下长度越短越好。
explain select * from emp,dept where emp.deptno = dept.deptno and emp.deptno = 10;
8、ref
显示索引的哪一列被应用了,如果可能的话,是一个常数
explain select * from emp,dept where emp.deptno = dept.deptno and emp.deptno = 10;
9、rows
依据表的统计信息及索引应用状况,大抵估算出找出所需记录须要读取的行数,此参数很重要,间接反馈的 sql 找了多少数据,在实现目标的状况下越少越好
explain select * from emp;
10、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