MySQL-sql执行计划

转载 2018年04月16日 11:39:53

MySql提供了EXPLAIN语法用来进行查询分析,在SQL语句前加一个"EXPLAIN"即可。

表头信息:id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra

id:id是位数字,表示查底中的执行select子句或操作表的顺序,如果id相同则执行顺序从上至下。如果是子查询,id的序号会递增,id越大则优先级越高,越先会被执行。id列为null的就标示这是一个结果集,不需要使用它来进行查询。

select_type:
    simple:连接查询的最外层查询。
    primary:子查询中的最外层查询。
    subquery:子查询的内层查询,结果不依赖于外部查询结果集。
    dependent subquery:子查询的内层查询,结果依赖于外部查询结果集。
    derived:派生表。
    union:复合查询。连接两个select查询,第一个查询是primary,第二个以后的表select_type都是union。
    dependent union:与union一样,出现在union 或union all语句中,结果依赖于外部查询结果集。

    union result:复合查询的合并结果。

table:显示的查询表名,如果查询使用了别名,那么这里显示的是别名。

type:
依次从好到差:system,const,eq_ref,ref,fulltext,ref_or_null,unique_subquery,index_subquery,range,index_merge,index,ALL。
除了all之外,其他的type都可以使用到索引,除了index_merge之外,其他的type只可以用到一个索引。
    system:表中只有一行数据或者是空表,且只能用于myisam和memory表。如果是Innodb引擎表,type列在这个情况通常都是all或者index。
    const:使用唯一索引或者主键,返回记录一定是1行记录。
    eq_ref:最多只会有一条匹配结果,一般是通过主键或者唯一键索引来访问。
    ref:非唯一索引扫描,返回匹配某个单独值的所有行。常见于使用非唯一索引或唯一索引的非唯一前缀进行的查找。
    fulltext:全文索引检索,要注意,全文索引的优先级很高,若全文索引和普通索引同时存在时,mysql不管代价,优先选择使用全文索引。
    ref_or_null:与ref方法类似,只是增加了null值的比较。实际用的不多。
    unique_subquery:用于where中的in形式子查询,子查询返回不重复值唯一值。
    index_subquery:用于in形式子查询使用到了辅助索引或者in常数列表,子查询可能返回重复值,可以使用索引将子查询去重。
    range:索引范围扫描,常见于使用>,<,is null,between ,in ,like等运算符的查询中。
    index_merge:表示查询使用了两个以上的索引,最后取交集或者并集。
    index:索引全表扫描。

依次从好到差:system,const,eq_ref,ref,fulltext,ref_or_null,unique_subquery,index_subquery,range,index_merge,index,ALL。
除了all之外,其他的type都可以使用到索引,除了index_merge之外,其他的type只可以用到一个索引。
    system:表中只有一行数据或者是空表,且只能用于myisam和memory表。如果是Innodb引擎表,type列在这个情况通常都是all或者index。
    const:使用唯一索引或者主键,返回记录一定是1行记录。
    eq_ref:最多只会有一条匹配结果,一般是通过主键或者唯一键索引来访问。
    ref:非唯一索引扫描,返回匹配某个单独值的所有行。常见于使用非唯一索引或唯一索引的非唯一前缀进行的查找。
    fulltext:全文索引检索,要注意,全文索引的优先级很高,若全文索引和普通索引同时存在时,mysql不管代价,优先选择使用全文索引。
    ref_or_null:与ref方法类似,只是增加了null值的比较。实际用的不多。
    unique_subquery:用于where中的in形式子查询,子查询返回不重复值唯一值。
    index_subquery:用于in形式子查询使用到了辅助索引或者in常数列表,子查询可能返回重复值,可以使用索引将子查询去重。
    range:索引范围扫描,常见于使用>,<,is null,between ,in ,like等运算符的查询中。
    index_merge:表示查询使用了两个以上的索引,最后取交集或者并集。
    index:索引全表扫描。

    all:全表扫描数据。

possible_keys :该查询可以利用的索引. 如果没有任何索引可以使用,就会显示成null,这一项内容对于优化时候索引的调整非常重要。

key:实际使用的索引。如果为NULL,则没有使用索引。

key_len:被选中使用索引的索引键长度。

ref:如果是使用的常数等值查询,这里会显示const,如果是连接查询,被驱动表的执行计划这里会显示驱动表的关联字段,如果是条件使用了表达式或者函数,或者条件列发生了内部隐式转换,这里可能显示为func。
 

rows:这里是执行计划中估算出来的结果集记录条数

extra:这个列可以显示的信息非常多,有几十种,常用的有:
    distinct:在select部分使用了distinc关键字
   Full scan on NULL key:子查询中的一种优化方式,主要在遇到无法通过索引访问null
值的使用使用。
   Impossible WHERE noticed after reading const tables:MySQL Query Optimizer 通过
收集到的统计信息判断出不可能存在结果。
   No tables:Query 语句中使用FROM DUAL 或者不包含任何FROM 子句。
    no tables used:不带from字句的查询或者From dual查询。
使用not in()形式子查询或not exists运算符的连接查询,这种叫做反连接。即,一般连接查询是先查询内表,再查询外表,反连接就是先查询外表,再查询内表。
    Not exists:在某些左连接中MySQL Query Optimizer 所通过改变原有Query 的组成而
使用的优化方法,可以部分减少数据访问次数。
    Range checked for each record (index map: N):通过MySQL 官方手册的描述,当
MySQL Query Optimizer 没有发现好的可以使用的索引的时候,如果发现如果来自前面的
表的列值已知,可能部分索引可以使用。对前面的表的每个行组合,MySQL 检查是否可以使
用range 或index_merge 访问方法来索取行。
    Select tables optimized away:当我们使用某些聚合函数来访问存在索引的某个字段的
时候,MySQL Query Optimizer 会通过索引而直接一次定位到所需的数据行完成整个查
询。当然,前提是在Query 中不能有GROUP BY 操作。如使用MIN()或者MAX()的时
候。

    using filesort:排序时无法使用到索引时,就会出现这个。常见于order by和group by语句中。
    using index:查询时不需要回表查询,直接通过索引就可以获取查询的数据。
    using_union:表示使用or连接各个使用索引的条件时,该信息表示从处理结果获取并集
    using intersect:表示使用and的各个索引的条件时,该信息表示是从处理结果获取交集
    using sort_union和using sort_intersection:与前面两个对应的类似,只是他们是出现在用and和or查询信息量大时,先查询主键,然后进行排序合并后,才能读取记录并返回。
    using where:表示存储引擎返回的记录并不是所有的都满足查询条件,需要在server层进行过滤。查询条件中分为限制条件和检查条件,5.6之前,存储引擎只能根据限制条件扫描数据并返回,然后server层根据检查条件进行过滤再返回真正符合查询的数据。5.6.x之后支持ICP特性,可以把检查条件也下推到存储引擎层,不符合检查条件和限制条件的数据,直接不读取,这样就大大减少了存储引擎扫描的记录数量。extra列显示using index condition
    using temporary:表示使用了临时表存储中间结果。临时表可以是内存临时表和磁盘临时表,执行计划中看不出来,需要查看status变量,used_tmp_table,used_tmp_disk_table才能看出来。
firstmatch(tb_name):5.6.x开始引入的优化子查询的新特性之一,常见于where字句含有in()类型的子查询。如果内表的数据量比较大,就可能出现这个
    loosescan(m..n):5.6.x之后引入的优化子查询的新特性之一,在in()类型的子查询中,子查询返回的可能有重复记录时,就可能出现这个   

    filtered:使用explain extended时会出现这个列,5.7之后的版本默认就有这个字段,不需要使用explain extended了。这个字段表示存储引擎返回的数据在server层过滤后,剩下多少满足查询的记录数量的比例,注意是百分比,不是具体记录数。




mysql-sql高级应用 sql语言进阶

mysql-sql高级应用 sql语言进阶   典型操作   order by - select * from play_list order by createtim...
  • qq_36030440
  • qq_36030440
  • 2016年12月27日 16:23
  • 134

【Oracle】三种方式查看SQL语句的执行计划

查看执行计划的方式有三种: EXPLAN PLAN 、V$SQL_PLAN 、SQL*PLUS AUTOTRACE1.EXPLAN PLAN: 显示执行相应语句时可以使用的理论计划 读取执行计划...
  • NextAction
  • NextAction
  • 2016年12月22日 01:01
  • 4028

mysql的sql执行计划详解(非常有用)

引言: 实际项目开发中,由于我们不知道实际查询的时候数据库里发生了什么事情,数据库软件是怎样扫描表、怎样使用索引的,因此,我们能感知到的就只有 sql语句运行的时间,在数据规模不大时,查询是瞬间的,因...
  • u012990533
  • u012990533
  • 2015年05月11日 14:10
  • 17122

SQL之执行计划

最近研究了一条存储过程,执行的时候速度超慢,便查了一下怎么分析,怎样看懂执行计划。 我用的工具是dbvisualizer 可以直接运行sql语句:select * into tableli...
  • zou1072585763
  • zou1072585763
  • 2017年04月27日 16:32
  • 1745

ORACLE执行计划的步骤和顺序

ORACLE执行计划的阅读方式,及执行步骤和顺序
  • qshpeng
  • qshpeng
  • 2010年08月18日 13:04
  • 5941

DB2执行计划

explain 1.如果第一次执行,请先(在dbinst用户下) connect to dbname, 执行db2 -tvf $HOME/sqllib/misc/EXPLAIN.DDL建立执行计划...
  • pingfandelanyangyang
  • pingfandelanyangyang
  • 2016年11月30日 17:26
  • 1603

[Oracle] 获取执行计划的各方法总结

总的结论: 一.获取执行计划的6种方法(详细步骤已经在每个例子的开头注释部分说明了): 1. explain plan for获取;  2. set autotrace on ;  3. st...
  • u010415792
  • u010415792
  • 2014年04月26日 09:49
  • 2769

Oracle执行计划中的索引

Oracle执行计划根据索引的类型与where限制条件的不同,有5种类型的索引扫描,分别是:索引唯一扫描(index unique scan),索引范围扫描(index range scan),索引全...
  • chenleixing
  • chenleixing
  • 2015年05月19日 08:40
  • 2037

Oracle 查看执行计划

-- Start 我们可以通过 EXPLAIN PLAN 语句生成执行计划,该语句把执行计划保存到一个叫做 PLAN_TABLE 的表中,我们可以通过查询这个表来查看执行计划。下面是一个简单例子。 ...
  • shangboerds
  • shangboerds
  • 2015年07月28日 12:52
  • 2109

查看Oracle执行计划的几种常用方法-系列1

SQL的执行计划实际代表了目标SQL在Oracle数据库内部的具体执行步骤,作为调优,只有知道了优化器选择的执行计划是否为当前情形下最优的执行计划,才能够知道下一步往什么方向。 执行计划的定...
  • bisal
  • bisal
  • 2014年08月30日 22:08
  • 25713
收藏助手
不良信息举报
您举报文章:MySQL-sql执行计划
举报原因:
原因补充:

(最多只允许输入30个字)