关于mysql:mysql执行计划就这样5000字被解释的清清楚楚

36次阅读

共计 5595 个字符,预计需要花费 14 分钟才能阅读完成。

上一次咱们 通过实际,解释了 mysql 主从复制的原理和实际,明天,咱们来看一下 mysql 的执行打算

在企业的利用场景中,为了晓得优化 SQL 语句的执行,须要查看 SQL 语句的具体执行过程,以放慢 SQL 语句的执行效率。

能够应用 explain+SQL 语句来模仿优化器执行 SQL 查问语句,从而晓得 mysql 是如何解决 sql 语句的。

1、执行打算中蕴含的信息

ColumnMeaningidThe SELECT identifierselect_typeThe SELECT typetableThe table for the output rowpartitionsThe matching partitionstypeThe join typepossible_keysThe possible indexes to choosekeyThe index actually chosenkey_lenThe length of the chosen keyrefThe columns compared to the indexrowsEstimate of rows to be examinedfilteredPercentage of rows filtered by table conditionextraAdditional information

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');

select_type

次要用来分辨查问的类型,是一般查问还是联结查问还是子查问

select_type ValueMeaningSIMPLESimple SELECT (not using UNION or subqueries)PRIMARYOutermost SELECTUNIONSecond or later SELECT statement in a UNIONDEPENDENT UNIONSecond or later SELECT statement in a UNION, dependent on outer queryUNION RESULTResult of a UNION.SUBQUERYFirst SELECT in subqueryDEPENDENT SUBQUERYFirst SELECT in subquery, dependent on outer queryDERIVEDDerived tableUNCACHEABLE SUBQUERYA subquery for which the result cannot be cached and must be re-evaluated for each row of the outer queryUNCACHEABLE UNIONThe second or later select in a UNION that belongs to an uncacheable subquery (see UNCACHEABLE SUBQUERY)

--sample: 简略的查问,不蕴含子查问和 unionexplain select * from emp;--primary: 查问中若蕴含任何简单的子查问,最外层查问则被标记为 Primaryexplain select staname,ename supname from (select ename staname,mgr from emp) t join emp on t.mgr=emp.empno ;--union: 若第二个 select 呈现在 union 之后,则被标记为 unionexplain 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 表获取后果的 selectexplain 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 语句未验证

table

对应行正在拜访哪一个表,表名或者别名,可能是长期表或者 union 合并后果集 1、如果是具体的表名,则表明从理论的物理表中获取数据,当然也能够是表的别名

2、表名是 derivedN 的模式,示意应用了 id 为 N 的查问产生的衍生表

3、当有 union result 的时候,表名是 union n1,n2 等的模式,n1,n2 示意参于 union 的 id

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 类型的特例,平时不会呈现

possible_keys

显示可能利用在这张表中的索引,一个或多个,查问波及到的字段上若存在索引,则该索引将被列出,但不肯定被查问理论应用

explain select * from emp,dept where emp.deptno = dept.deptno and emp.deptno = 10;

key

理论应用的索引,如果为 null,则没有应用索引,查问中若应用了笼罩索引,则该索引和查问的 select 字段重叠。

explain select * from emp,dept where emp.deptno = dept.deptno and emp.deptno = 10;

key_len

示意索引中应用的字节数,能够通过 key_len 计算查问中应用的索引长度,在不损失精度的状况下长度越短越好。

explain select * from emp,dept where emp.deptno = dept.deptno and emp.deptno = 10;

ref

显示索引的哪一列被应用了,如果可能的话,是一个常数

explain select * from emp,dept where emp.deptno = dept.deptno and emp.deptno = 10;

rows

依据表的统计信息及索引应用状况,大抵估算出找出所需记录须要读取的行数,此参数很重要,间接反馈的 sql 找了多少数据,在实现目标的状况下越少越好

explain select * from emp;

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 语句的后果总是 falseexplain select * from emp where empno = 7469;

感觉写的不错的,欢送关注 + 转发吧,您的激励是我持续的最大能源
相应的文章曾经整顿造成文档,git 扫码获取材料看这里

https://gitee.com/biwangsheng/personal.git

正文完
 0