`
g21121
  • 浏览: 686209 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

EXPLAIN结果列说明

阅读更多

        EXPLAIN 命令主要用于分析MySQL 的SQL 语句效率,EXPLAIN 命令在MySql 5.6版本之后不仅仅只支持SELECT 条件分析,还增加了DELETE、INSERT、REPLACE、UPDATE的支持,以下就是EXPLAIN 命令的语法:

{EXPLAIN | DESCRIBE | DESC}
    tbl_name [col_name | wild]

{EXPLAIN | DESCRIBE | DESC}
    [explain_type]
    explainable_stmt

explain_type: {
    EXTENDED
  | PARTITIONS
  | FORMAT = format_name
}

format_name: {
    TRADITIONAL
  | JSON
}

explainable_stmt: {
    SELECT statement
  | DELETE statement
  | INSERT statement
  | REPLACE statement
  | UPDATE statement
}

        一般情况下我们会使用EXPLAIN 去分析发生过的慢查询语句,诸如:

mysql> explain select * from table_a\G
********** 1. row **********
           id: 1
  select_type: SIMPLE
        table: table_a
   partitions: NULL
         type: ALL
possible_keys: NULL
          key: NULL
      key_len: NULL
          ref: NULL
         rows: 2
     filtered: 100.00
        Extra: NULL

        这些结果类型分别代表了不同的意义,每一个类型均有不同的属性值,不同属性的值代表了不同的效率与性能,本文就针对这些属性进行分析与学习。

 

        1.id

        识别符,每行结果都会有一个id

 

        2.select_type

        select 类型,值为以下其中一种:

        SIMPLE:进行不需要union 操作或不含子查询的简单select 查询时,响应查询语句的select_type 为SIMPLE(查询中包含连接的情形也一样)。无论查询语句是多么复杂,执行计划中select_type为SIMPLE的单位查询一定只有一个,即最外侧的select查询的select_type通常为SIMPLE。上面那个示例的select_type 就是SIMPLE 类型的。

 

        PRIMARY:一个需要union 操作或含子查询的select 查询执行计划中,位于最外层的select_type 即为PRIMARY。与SIMPLE 一样,select_type 为PRIMARY 的单位select 查询也只存在1个,位于查询最外侧的select 单位查询的select_type 为PRIMARY

 

        UNION:UNION 中的第二个或后面的SELECT 语句,由union 操作联合而成的单位select 查询中,除第一个外,第二个以后的所有单位select 查询的select_type 都为UNION。union 的第一个单位select 的select_type 不是UNION,而是DERIVED。它是一个临时表,用于存储联合(Union)后的查询结果。

mysql> explain select * from table_a where num in
(select num from table_a where `status`='NORMAL' 
union 
select num from table_b where `status`='NORMAL')\G
********** 1. row **********
           id: 1
  select_type: PRIMARY
        table: table_a
   partitions: NULL
         type: ALL
possible_keys: NULL
          key: NULL
      key_len: NULL
          ref: NULL
         rows: 3
     filtered: 100.00
        Extra: Using where
********** 2. row **********
           id: 2
  select_type: DEPENDENT SUBQUERY
        table: table_a
   partitions: NULL
         type: eq_ref
possible_keys: AK_key_2
          key: AK_key_2
      key_len: 98
          ref: func
         rows: 1
     filtered: 33.33
        Extra: Using where
********** 3. row **********
           id: 3
  select_type: DEPENDENT UNION
        table: table_b
   partitions: NULL
         type: eq_ref
possible_keys: AK_key_2
          key: AK_key_2
      key_len: 98
          ref: func
         rows: 1
     filtered: 33.33
        Extra: Using where
********** 4. row **********
           id: NULL
  select_type: UNION RESULT
        table: <union2,3>
   partitions: NULL
         type: ALL
possible_keys: NULL
          key: NULL
      key_len: NULL
          ref: NULL
         rows: NULL
     filtered: NULL
        Extra: Using temporary

 

        3个联合查询中,只有第一个(table_a)不是union,其余两个的select_type均为union。union 的第一个查询设置为代表整个union 结果的select_type类型。此外要将3个子查询的结果用union all进行联合,并创建临时表进行使用,所以union all的第一个查询的select_type为DERIVED。

 

        DEPENDENT UNION:UNION 中的第二个或后面的SELECT 语句,取决于外面的查询,与UNION  select_type 一样,DEPENDENT UNION 出现在union 或union all 形成的集合查询中。此处的dependent 表示union 或union all 联合而成的单位查询受外部影响。下列查询中,两个select 查询用union 联合起来,所以union 出现在select_type中,从in所包含的子查询中可以看到,两个查询通过union连接在一起。不会在默认优化器模式下先处理IN(subquery)查询内部的子查询,而是读取外部的employees数据表,再执行子查询时,dependent关键字就会出现在select_type中。

        一个单位的select查询中还包含其他单位select时,我们将内部的select 查询语句称为子查询,一个查询中含有子查询时,子查询通常会比外部查询先执行,这种处理方式的速度一般会非常快。但对于select type包含dependent关键字的子查询,由于它要依赖外部查询,所以绝对不会比外部查询先执行。因此,select_type包含dependent关键字的子查询先执行往往会比较低效。

 

        UNION RESULT:UNION 的结果,union result为包含union结果的数据表。union all或union(DISTINCT)查询会将所有union结果创建为临时表。执行计划中,该临时表所在行为select_type为union result。由于union result在实际查询中不是单位查询,所以没有单独的id值。

 

        SUBQUERY:子查询中的第一个SELECT

        DEPENDENT SUBQUERY:子查询中的第一个SELECT,取决于外面的查询

        DERIVED:from子句中出现的子查询,也就是示例中的(select * from table_a)。

        DELETE:删除操作

        UPDATE:更新操作

        INSERT:插入操作

        REPLACE:替换操作

        以下是一个示例:

mysql> explain select * from table_a where num in
(select num from table_a where `status`='NORMAL' 
union 
select num from table_b where `status`='NORMAL')\G
********** 1. row **********
           id: 1
  select_type: PRIMARY
        table: table_a
   partitions: NULL
         type: ALL
possible_keys: NULL
          key: NULL
      key_len: NULL
          ref: NULL
         rows: 3
     filtered: 100.00
        Extra: Using where
********** 2. row **********
           id: 2
  select_type: DEPENDENT SUBQUERY
        table: table_a
   partitions: NULL
         type: eq_ref
possible_keys: AK_key_2
          key: AK_key_2
      key_len: 98
          ref: func
         rows: 1
     filtered: 33.33
        Extra: Using where
********** 3. row **********
           id: 3
  select_type: DEPENDENT UNION
        table: table_b
   partitions: NULL
         type: eq_ref
possible_keys: AK_key_2
          key: AK_key_2
      key_len: 98
          ref: func
         rows: 1
     filtered: 33.33
        Extra: Using where
********** 4. row **********
           id: NULL
  select_type: UNION RESULT
        table: <union2,3>
   partitions: NULL
         type: ALL
possible_keys: NULL
          key: NULL
      key_len: NULL
          ref: NULL
         rows: NULL
     filtered: NULL
        Extra: Using temporary

  

        3.table

        查询目标,这里不一定是一个物理表名。

 

        4.partitions

        partitions 列代表给定表所使用的分区。这一列只会在EXPLAIN PARTITIONS 语句中出现。

 

        5.type

        type是一个非常重要的属性列,它的值基本能直接反应出被分析SQL的效率高低。

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行记录的等值where条件时,通常type是const。其他数据库也叫做唯一索引扫描

        eq_ref:出现在要连接过个表的查询计划中,驱动表只返回一行数据,且这行数据是第二个表的主键或者唯一索引,且必须为not null,唯一索引和主键是多列时,只有所有的列都用作比较时才会出现eq_ref

        ref:不像eq_ref那样要求连接顺序,也没有主键和唯一索引的要求,只要使用相等条件检索时就可能出现,常见与辅助索引的等值查找。或者多列主键、唯一索引中,使用第一个列之外的列作为等值查找也会出现,总之,返回数据不唯一的等值查找就可能出现。

        fulltext:全文索引检索,要注意,全文索引的优先级很高,若全文索引和普通索引同时存在时,mysql不管代价,优先选择使用全文索引

        ref_or_null:与ref方法类似,只是增加了null值的比较。实际用的不多。

        unique_subquery:用于where中的in形式子查询,子查询返回不重复值唯一值

        index_subquery:用于in形式子查询使用到了辅助索引或者in常数列表,子查询可能返回重复值,可以使用索引将子查询去重。

        range:索引范围扫描,常见于使用>,<,is null,between ,in ,like等运算符的查询中。

        index_merge:表示查询使用了两个以上的索引,最后取交集或者并集,常见and ,or的条件使用了不同的索引,官方排序这个在ref_or_null之后,但是实际上由于要读取所个索引,性能可能大部分时间都不如range

        index:索引全表扫描,把索引从头到尾扫一遍,常见于使用索引列就可以处理不需要读取数据文件的查询、可以使用索引排序或者分组的查询。

        ALL:这个就是全表扫描数据文件,然后再在server层进行过滤返回符合要求的记录。

 

        6.possible_keys

        指出MySQL能使用哪个索引在该表中找到结果。

 

        7.key

        查询真正使用到的索引,select_type为index_merge时,这里可能出现两个以上的索引,其他的select_type这里只会出现一个。

 

        8.key_len

        用于处理查询的索引长度,如果是单列索引,那就等于整个索引长度,如果是多列索引,那么查询不一定都能使用到所有的列,具体使用到了多少个列的索引,这里就会计算进去,没有使用到的列,这里不会计算进去。留意下这个列的值,算一下你的多列索引总长度就知道有没有使用到所有的列了。要注意,mysql的ICP特性使用到的索引不会计入其中。另外,key_len只计算where条件用到的索引长度,而排序和分组就算用到了索引,也不会计算到key_len中。

 

        9.ref

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

 

        10.rows

        这里是执行计划中估算的扫描行数,不是精确值。

 

        11.filtered

        显示了通过条件过滤出的行数的百分比估计值。

 

        12.extra

        这个列可以显示的信息非常多,常用的有

        distinct:在select部分使用了distinc关键字

        no tables used:不带from字句的查询或者From dual查询

使用not in()形式子查询或not exists运算符的连接查询,这种叫做反连接。即,一般连接查询是先查询内表,再查询外表,反连接就是先查询外表,再查询内表。

        using filesort:排序时无法使用到索引时,就会出现这个。常见于order by和group by语句中

        using index:查询时不需要回表查询,直接通过索引就可以获取查询的数据。

        using join buffer(block nested loop),using join buffer(batched key accss):5.6.x之后的版本优化关联查询的BNL,BKA特性。主要是减少内表的循环数量以及比较顺序地扫描查询。

        using sort_union,using_union,using intersect,using sort_intersection:

        using intersect:表示使用and的各个索引的条件时,该信息表示是从处理结果获取交集

        using union:表示使用or连接各个使用索引的条件时,该信息表示从处理结果获取并集

        using sort_union和using sort_intersection:与前面两个对应的类似,只是他们是出现在用and和or查询信息量大时,先查询主键,然后进行排序合并后,才能读取记录并返回。

        using temporary:表示使用了临时表存储中间结果。临时表可以是内存临时表和磁盘临时表,执行计划中看不出来,需要查看status变量,used_tmp_table,used_tmp_disk_table才能看出来。

        using where:表示存储引擎返回的记录并不是所有的都满足查询条件,需要在server层进行过滤。查询条件中分为限制条件和检查条件,5.6之前,存储引擎只能根据限制条件扫描数据并返回,然后server层根据检查条件进行过滤再返回真正符合查询的数据。5.6.x之后支持ICP特性,可以把检查条件也下推到存储引擎层,不符合检查条件和限制条件的数据,直接不读取,这样就大大减少了存储引擎扫描的记录数量。extra列显示using index condition

        firstmatch(tb_name):5.6.x开始引入的优化子查询的新特性之一,常见于where字句含有in()类型的子查询。如果内表的数据量比较大,就可能出现这个

        loosescan(m..n):5.6.x之后引入的优化子查询的新特性之一,在in()类型的子查询中,子查询返回的可能有重复记录时,就可能出现这个

  • 大小: 12.2 KB
分享到:
评论

相关推荐

    MySQL中通过EXPLAIN如何分析SQL的执行计划详解

    下面分别对EXPLAIN命令结果的每一列进行说明: .select_type:表示SELECT的类型,常见的取值有: 类型 说明 SIMPLE 简单表,不使用表连接或子查询 PRIMARY 主查询,即外层的查询 UNION UNION中的第二...

    MySQL,通过explain分析低效SQL的执行计划。

    结果列说明: select_type:SELECT、SIMPLE(简单表,即不使用表连接和子查询)、PRIMARY(主查询,即外层的查询)、UNION(union中的第二个或后面的查询语句)、SUBQUERY(子查询中的第一个select) table:输出...

    DB2错误信息SQLCODE SQLSTATE.txt

    db2sql存储table数据库nullsqlcode sqlstate 说明 000 00000 SQL语句成功完成 01xxx SQL语句成功完成,但是有警告 +012 01545 未限定的列名被解释为一个有相互关系的引用 +098 01568 动态SQL语句用分号结束...

    MongoDB如何查询耗时记录的方法详解

    准备 在此之前,我们先在我们的数据库中插入10万条数据。数据的格式是这样的: { "name":"your name", ...queryPlanner:默认参数,详细说明查询优化器选择的计划并列出被拒绝的计划。例如: d

    reportx2.7表格控件

    setcellvalue()置单元格文本、getcellvalue()取单元格文本、Explain...()计算刷新单元格公式、OpenReport()载入表格模版、Colcount和Rowcount属性设置或取得表格行列数、 GetSelectCell方法的参数应使用变量而不是...

    语句性能分析之索引、内存、性能优化

    在应用系统开发初期,由于系统数据量比较少,sql语句的性能能优劣无法体现出来,但系统提交到生产环境后,随着...id列数字越大越先执行,如果说数字一样大,那么就从上往下依次执行,id列为null的就表是这是一个结果集

    SQL性能优化

    说明:对查询结果进行排序会大大的降低系统的性能,group与union都会对数据作排序,要耗费较多的内存,视状况用union all既可,不然有时数据太大又要进行union的排序,会导致Oracle数据库SORT_AREA_SIZE不足发生系统...

    MYSQL培训经典教程(共两部分) 2/2

    数据库优化 177 8.1 索引的使用 178 8.1.1索引对单个表查询的影响 ...列 186 8.2.3 总结 187 8.3 SQL查询的优化 187 8.3.1 使用EXPLAIN语句检查SQL语句 187 8.3.2 SELECT 查询的速度 188 8.3.2.1 ...

    MYSQL培训经典教程(共两部分) 1/2

    数据库优化 177 8.1 索引的使用 178 8.1.1索引对单个表查询的影响 ...列 186 8.2.3 总结 187 8.3 SQL查询的优化 187 8.3.1 使用EXPLAIN语句检查SQL语句 187 8.3.2 SELECT 查询的速度 188 8.3.2.1 ...

    ORACLE重建索引总结

    这列是说明索引从根块到叶快的级别,或是深度。如果级别大于等于4。则需要重建, 如下 :Select index_name,blevel from dba_indexes where blevel&gt;=4. 另一个从重建中受益的指标显然是当该索引中的被删除项占总...

    MySQL中文参考手册

    o 4.10 Perl 安装说明 + 4.10.1 在Unix操作系统上安装 Perl + 4.10.2 在 Win32上安装 ActiveState Perl + 4.10.3 在 Win32 上安装 MySQL Perl 分发 + 4.10.4 使用 Perl DBI/DBD接口遇到的问题 o 4.11 系统特定...

    oracle_fdw:适用于Oracle的PostgreSQL外部数据包装器

    oracle_fdw是PostgreSQL扩展,提供了Foreign Data Wrapper,可以轻松,高效地访问Oracle数据库,包括下推WHERE条件和所需的列以及全面的EXPLAIN支持。 本自述包含以下部分: oracle_fdw由Laurenz Albe编写,由...

    记录一次SQL优化

    一大早到公司,加班一宿的同事跟我抱怨,说,一个表只有8w条数据,需要更新一列,根据目前进度估算,大概需要3个小时,即使不需要更新,查询每条数据也需要400ms左右;  或许确实配置太低,或许确实表的字段太多,...

    HCIP-GaussDB-OLAP V1.0视频.zip

    5.10 ETL工具、Migration工具使用说明 5.11 查询执行流程及Explain执行计划 5.12 Plan Hint及调优原则 5.13 调优流程及静态调优 5.14 动态调优 5.15 高危操作列表、故障处理流程及定界 5.16 故障定位 5.17 应急处理 ...

    MYSQL

    7.18 USE (使用)句法 7.19 FLUSH (清除缓存)句法 7.20 KILL (杀灭)句法 7.21 SHOW (显示)句法(得到关于表,列等的信息) 7.22 EXPLAIN (解释)句法(得到关于SELECT的信息) 7.23 DESCRIBE ...

    MySQL中文参考手册.chm

    7.22 EXPLAIN (解释)句法(得到关于SELECT的信息) 7.23 DESCRIBE (描述)句法(得到列的信息) 7.24 LOCK TABLES/UNLOCK TABLES (锁定表/解锁表)句法 7.25 SET OPTION (设置选项)句法 7.26 ...

    达梦数据库用户手册基础学习版.rar

    4.5 合并查询结果 202 4.6 GROUP BY 和 HAVING 子句 204 4.6.1 GROUP BY 子句的使用 204 4.6.2 ROLLUP 的使用 205 4.6.3 CUBE 的使用 206 4.6.4 GROUPING 的使用 208 4.6.5 GROUPING SETS 的使用 209 4.6.6 ...

    面向对象分析与设计(第3版) Object Oriented Analysis And Design With Applications 3Rd Edition

    本书通过大量例子说明了基本概念,解释了方法,并展示了在不同领域的成功应用。全书分为理论和应用两部分。理论部分深刻剖析了面向对象分析与设计 (OOAD)的概念和方法。应用部分连续列出了5个不同类型、不同领域的...

    深入云计算 MongoDB管理与开发实战详解pdf.part1

    12.5.1 列出所有的Shard Server 12.5.2 查看Sharding信息 12.5.3 判断是否是Sharding 12.5.4 对现有的集合进行Sharding 12.5.5 新增Shard Server 12.5.6 移除Shard Server 12.6 本章小结 第13章...

Global site tag (gtag.js) - Google Analytics