explain 订阅
explain,其义为解释,阐述,说明。在英语语法中,有及物动词(vt.)和不及物动词(vi.)之分,不同语法下其义及使用方法不同。 展开全文
explain,其义为解释,阐述,说明。在英语语法中,有及物动词(vt.)和不及物动词(vi.)之分,不同语法下其义及使用方法不同。
信息
外文名
explain
音标-美式
ɪkˈsplen
音标-英式
iksˈplein
含    义
解释,阐述
动词分类
vt.,vi.
中文名
解释
explain词语解释
及物动词(vt.)1. 解释;说明;阐明[(+to)][+wh-][+(that)]He explained that he had been cheated.他解释说他是上当受骗了。Can you explain how the machine operates?你能解释一下这机器是如何运转的吗?Please explain this rule to me.请给我讲解一下这条规则。2. 为...辩解;说明...的理由(或原因)[+wh-]He made up a story to explain why he was absent.他编造了一个故事为他的缺席辩解。不及物动词(vi.)1. 解释;说明;辩解I've got to explain about it.我得解释一下此事。
收起全文
精华内容
下载资源
问答
  • EXPLAIN

    2017-11-25 14:36:52
    MySQL 提供了一个 EXPLAIN 命令, 它可以对 SELECT 语句进行分析, 并输出 SELECT 执行的详细信息, 以供开发人员针对性优化. EXPLAIN 命令用法十分简单, 在 SELECT 语句前加上 Explain 就可以了, 例如: EXPLAIN ...
    
    
    MySQL 提供了一个 EXPLAIN 命令, 它可以对 SELECT 语句进行分析, 并输出 SELECT 执行的详细信息, 以供开发人员针对性优化.

    EXPLAIN 命令用法十分简单, 在 SELECT 语句前加上 Explain 就可以了, 例如:

    EXPLAIN SELECT * from user_info WHERE id < 300; 

    各列的含义如下:

    1. id: SELECT 查询的标识符. 每个 SELECT 都会自动分配一个唯一的标识符.
    2. select_type: SELECT 查询的类型.
    3. table: 查询的是哪个表
    4. partitions: 匹配的分区
    5. type: join 类型
    6. possible_keys: 此次查询中可能选用的索引
    7. key: 此次查询中确切使用到的索引.
    8. ref: 哪个字段或常数与 key 一起被使用
    9. rows: 显示此查询一共扫描了多少行. 这个是一个估计值.
    10. filtered: 表示此查询条件所过滤的数据的百分比
    11. extra: 额外的信息

    接下来我们来重点看一下比较重要的几个字段.


    展开全文
  • explain

    千次阅读 2019-03-26 13:47:12
    id值不相同:这种情况下,id值会自递增,id值越大,explain结果中的相应sql语句被执行的优先级越高,越先被执行。这通常会在子查询中出现 id值存在相同的和不同的值:这种情况下,id值越大,优先级越高,越先被执行...

     

    这个字段是用来确定查询语句执行的优先级的。

    这个值会有三种情况:

    id值相同:这种情况意味着查询语句按照explain结果中的id自上而下执行

    id值不相同:这种情况下,id值会自递增,id值越大,explain结果中的相应sql语句被执行的优先级越高,越先被执行。这通常会在子查询中出现

    id值存在相同的和不同的值:这种情况下,id值越大,优先级越高,越先被执行,那么,对于id值相同的结果,mysql会按照explain结果中的id自上而下执行。

    select_type

    表示查询的类型,先看表

     

    PRIMARY:查询中若包含若干子查询或者嵌套查询,那么最外层的查询将被标记为PRIMARY.

    SUBQUERY:在select或where语句中包含子查询

    DERIVED:在from列表中包含的子查询将被标记为DERIVED(衍生),MySQL会递归执行这些子查询,将结果放在临时表中。

    table

    对应行正在访问哪一个表,表名或者别名,有可能是一下几种

    1 实际的表名  

    2 表的别名

    比如 select * from customer as c

    3 derived  子查询

    <derivedx>, x是个数字,我的理解是第几步执行的结果

    4 null 直接结算的结果,不走表

    关联优化器会为查询选择关联顺序,左侧深度优先

    当from中有子查询的时候,表名是derivedN的形式,N指向子查询,也就是explain结果中的下一列

    当有union result的时候,表名是union 1,2等的形式,1,2表示参与union的query id

    注意:MySQL对待这些表和普通表一样,但是这些“临时表”是没有任何索引的。

     

    type:

    type显示的是访问类型,是较为重要的一个指标,结果值从好到坏依次是:

    system > const > eq_ref > ref > fulltext > ref_or_null > index_merge > unique_subquery > index_subquery > range > index > ALL ,一般来说,得保证查询至少达到range级别,最好能达到ref。

     

    ref            使用非唯一索引扫描或唯一索引前缀扫描(有时候需要索引很长的字符列,这会让索引变得大且慢。通常可以索引开始的部分字符,这样可以大大节约索引空间,从而提高索引效率),返回单条记录,常出现在关联查询中

    eq_ref         类似ref,区别在于使用的是唯一索引,使用主键的关联查询

    possible_keys

      指出MySQL能使用哪个索引在表中找到记录,查询涉及到的字段上若存在索引,则该索引将被列出,但不一定被查询使用

      该列完全独立于EXPLAIN输出所示的表的次序。这意味着在possible_keys中的某些键实际上不能按生成的表次序使用。

      如果该列是NULL,则没有相关的索引。在这种情况下,可以通过检查WHERE子句看是否它引用某些列或适合索引的列来提高你的查询性能。如果是这样,创造一个适当的索引并且再次用EXPLAIN检查查询

     

    key

    显示MySQL实际决定使用的键(索引)。如果没有选择索引,键是NULL。要想强制MySQL使用或忽视possible_keys列中的索引,在查询中使用FORCE INDEX、USE INDEX或者IGNORE INDEX。

    key_len

    key_len列显示MySQL决定使用的键长度。如果键是NULL,则长度为NULL。使用的索引的长度。在不损失精确性的情况下,长度越短越好 。

    表示查询优化器使用了索引的字节数. 这个字段可以评估组合索引是否完全被使用, 或只有最左部分字段被使用到.

    key_len 的计算规则如下:

    字符串

    char(n): n 字节长度

    varchar(n): 如果是 utf8 编码, 则是 3 n + 2字节; 如果是 utf8mb4 编码, 则是 4 n + 2 字节.

    数值类型:

    TINYINT: 1字节

    SMALLINT: 2字节

    MEDIUMINT: 3字节

    INT: 4字节

    BIGINT: 8字节

    时间类型

    DATE: 3字节

    TIMESTAMP: 4字节

    DATETIME: 8字节

    字段属性: NULL 属性 占用一个字节. 如果一个字段是 NOT NULL 的, 则没有此属性.

    我们来举两个简单的栗子:

    mysql> EXPLAIN SELECT * FROM order_info WHERE user_id < 3 AND product_name = 'p1' AND productor = 'WHH' \G
    *************************** 1. row ***************************
               id: 1
      select_type: SIMPLE
            table: order_info
       partitions: NULL
             type: range
    possible_keys: user_product_detail_index
              key: user_product_detail_index
          key_len: 9
              ref: NULL
             rows: 5
         filtered: 11.11
            Extra: Using where; Using index
    
    1 row in set, 1 warning (0.00 sec)

    上面的例子是从表 order_info 中查询指定的内容, 而我们从此表的建表语句中可以知道, 表 order_info 有一个联合索引:

    KEY `user_product_detail_index` (`user_id`, `product_name`, `productor`)

    不过此查询语句 WHERE user_id < 3 AND product_name = 'p1' AND productor = 'WHH' 中, 因为先进行 user_id 的范围查询, 而根据 最左前缀匹配 原则, 当遇到范围查询时, 就停止索引的匹配, 因此实际上我们使用到的索引的字段只有 user_id, 因此在 EXPLAIN 中, 显示的 key_len 为 9. 因为 user_id 字段是 BIGINT, 占用 8 字节, 而 NULL 属性占用一个字节, 因此总共是 9 个字节. 若我们将user_id 字段改为 BIGINT(20) NOT NULL DEFAULT '0', 则 key_length 应该是8.

    上面因为 最左前缀匹配 原则, 我们的查询仅仅使用到了联合索引的 user_id 字段, 因此效率不算高.

     

    接下来我们来看一下下一个例子:

    mysql> EXPLAIN SELECT * FROM order_info WHERE user_id = 1 AND product_name = 'p1' \G;
    
    *************************** 1. row ***************************
               id: 1
      select_type: SIMPLE
            table: order_info
       partitions: NULL
             type: ref
    possible_keys: user_product_detail_index
              key: user_product_detail_index
          key_len: 161
              ref: const,const
             rows: 2
         filtered: 100.00
            Extra: Using index
    1 row in set, 1 warning (0.00 sec)

           这次的查询中, 我们没有使用到范围查询, key_len 的值为 161. 为什么呢? 因为我们的查询条件 WHERE user_id = 1 AND product_name = 'p1' 中, 仅仅使用到了联合索引中的前两个字段, 因此 keyLen(user_id) + keyLen(product_name) = 9 + 50 * 3 + 2 = 161

    rows

    rows 也是一个重要的字段. MySQL 查询优化器根据统计信息, 估算 SQL 要查找到结果集需要扫描读取的数据行数.

    这个值非常直观显示 SQL 的效率好坏, 原则上 rows 越少越好.

    Extra

    EXplain 中的很多额外的信息会在 Extra 字段显示, 常见的有以下几种内容:

     

    Using join buffer:改值强调了在获取连接条件时没有使用索引,并且需要连接缓冲区来存储中间结果。如果出现了这个值,那应该注意,根据查询的具体情况可能需要添加索引来改进能。

    总结:

    • EXPLAIN不会告诉你关于触发器、存储过程的信息或用户自定义函数对查询的影响情况

    • EXPLAIN不考虑各种Cache

    • EXPLAIN不能显示MySQL在执行查询时所作的优化工作

    • 部分统计信息是估算的,并非精确值

    • EXPALIN只能解释SELECT操作,其他操作要重写为SELECT后查看执行计划。

     

    filtered:表示示此查询条件所过滤的数据的百分比

     

    expain出来的信息有10列,分别是id、select_type、table、type、possible_keys、key、key_len、ref、rows、Extra,下面对这些字段出现的可能进行解释:

    一、 id

         我的理解是SQL执行的顺序的标识,SQL从大到小的执行

    1. id相同时,执行顺序由上至下

    2. 如果是子查询,id的序号会递增,id值越大优先级越高,越先被执行

    3.id如果相同,可以认为是一组,从上往下顺序执行;在所有组中,id值越大,优先级越高,越先执行

     

     

    二、select_type

          示查询中每个select子句的类型

    (1) SIMPLE(简单SELECT,不使用UNION或子查询等)

    (2) PRIMARY(查询中若包含任何复杂的子部分,最外层的select被标记为PRIMARY)

    (3) UNION(UNION中的第二个或后面的SELECT语句)

    (4) DEPENDENT UNION(UNION中的第二个或后面的SELECT语句,取决于外面的查询)

    (5) UNION RESULT(UNION的结果)

    (6) SUBQUERY(子查询中的第一个SELECT)

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

    (8) DERIVED(派生表的SELECT, FROM子句的子查询)

    (9) UNCACHEABLE SUBQUERY(一个子查询的结果不能被缓存,必须重新评估外链接的第一行)

     

    三、table

    显示这一行的数据是关于哪张表的,有时不是真实的表名字,看到的是derivedx(x是个数字,我的理解是第几步执行的结果)

     

    mysql> explain select * from (select * from ( select * from t1 where id=2602) a) b;
    +----+-------------+------------+--------+-------------------+---------+---------+------+------+-------+
    | id | select_type | table      | type   | possible_keys     | key     | key_len | ref  | rows | Extra |
    +----+-------------+------------+--------+-------------------+---------+---------+------+------+-------+
    |  1 | PRIMARY     | <derived2> | system | NULL              | NULL    | NULL    | NULL |    1 |       |
    |  2 | DERIVED     | <derived3> | system | NULL              | NULL    | NULL    | NULL |    1 |       |
    |  3 | DERIVED     | t1         | const  | PRIMARY,idx_t1_id | PRIMARY | 4       |      |    1 |       |
    +----+-------------+------------+--------+-------------------+---------+---------+------+------+-------+

     

     

    四、type

    表示MySQL在表中找到所需行的方式,又称“访问类型”。

    常用的类型有: ALL, index,  range, ref, eq_ref, const, system, NULL(从左到右,性能从差到好)

    ALL:Full Table Scan, MySQL将遍历全表以找到匹配的行

    index: Full Index Scan,index与ALL区别为index类型只遍历索引树

    range:只检索给定范围的行,使用一个索引来选择行

    ref: 表示上述表的连接匹配条件,即哪些列或常量被用于查找索引列上的值

    eq_ref: 类似ref,区别就在使用的索引是唯一索引,对于每个索引键值,表中只有一条记录匹配,简单来说,就是多表连接中使用primary key或者 unique key作为关联条件

    const、system: 当MySQL对查询某部分进行优化,并转换为一个常量时,使用这些类型访问。如将主键置于where列表中,MySQL就能将该查询转换为一个常量,system是const类型的特例,当查询的表只有一行的情况下,使用system

    NULL: MySQL在优化过程中分解语句,执行时甚至不用访问表或索引,例如从一个索引列里选取最小值可以通过单独索引查找完成。

     

    五、possible_keys

    指出MySQL能使用哪个索引在表中找到记录,查询涉及到的字段上若存在索引,则该索引将被列出,但不一定被查询使用

    该列完全独立于EXPLAIN输出所示的表的次序。这意味着在possible_keys中的某些键实际上不能按生成的表次序使用。
    如果该列是NULL,则没有相关的索引。在这种情况下,可以通过检查WHERE子句看是否它引用某些列或适合索引的列来提高你的查询性能。如果是这样,创造一个适当的索引并且再次用EXPLAIN检查查询

     

    六、Key

    key列显示MySQL实际决定使用的键(索引)

    如果没有选择索引,键是NULL。要想强制MySQL使用或忽视possible_keys列中的索引,在查询中使用FORCE INDEX、USE INDEX或者IGNORE INDEX。

     

    七、key_len

    表示索引中使用的字节数,可通过该列计算查询中使用的索引的长度(key_len显示的值为索引字段的最大可能长度,并非实际使用长度,即key_len是根据表定义计算而得,不是通过表内检索出的)

    不损失精确性的情况下,长度越短越好 

     

    八、ref

    表示上述表的连接匹配条件,即哪些列或常量被用于查找索引列上的值

     

    九、rows

     表示MySQL根据表统计信息及索引选用情况,估算的找到所需的记录所需要读取的行数

     

    十、Extra

    该列包含MySQL解决查询的详细信息,有以下几种情况:

    Using where:列数据是从仅仅使用了索引中的信息而没有读取实际的行动的表返回的,这发生在对表的全部的请求列都是同一个索引的部分的时候,表示mysql服务器将在存储引擎检索行后再进行过滤

    Using temporary:表示MySQL需要使用临时表来存储结果集,常见于排序和分组查询

    Using filesort:MySQL中无法利用索引完成的排序操作称为“文件排序”

    Using join buffer:改值强调了在获取连接条件时没有使用索引,并且需要连接缓冲区来存储中间结果。如果出现了这个值,那应该注意,根据查询的具体情况可能需要添加索引来改进能。

    Impossible where:这个值强调了where语句会导致没有符合条件的行。

    Select tables optimized away:这个值意味着仅通过使用索引,优化器可能仅从聚合函数结果中返回一行

     

     

    总结:
    • EXPLAIN不会告诉你关于触发器、存储过程的信息或用户自定义函数对查询的影响情况
    • EXPLAIN不考虑各种Cache
    • EXPLAIN不能显示MySQL在执行查询时所作的优化工作
    • 部分统计信息是估算的,并非精确值
    • EXPALIN只能解释SELECT操作,其他操作要重写为SELECT后查看执行计划。

    展开全文
  • [MySQL高级](一) EXPLAIN用法和结果分析

    万次阅读 多人点赞 2018-05-21 09:41:23
    1. EXPLAIN简介 使用EXPLAIN关键字可以模拟优化器执行SQL查询语句,从而知道MySQL是如何处理你的SQL语句的。分析你的查询语句或是表结构的性能瓶颈。 ➤ 通过EXPLAIN,我们可以分析出以下结果: 表的读取顺序 ...

    1. EXPLAIN简介

    使用EXPLAIN关键字可以模拟优化器执行SQL查询语句,从而知道MySQL是如何处理你的SQL语句的。分析你的查询语句或是表结构的性能瓶颈。
    通过EXPLAIN,我们可以分析出以下结果:

    • 表的读取顺序
    • 数据读取操作的操作类型
    • 哪些索引可以使用
    • 哪些索引被实际使用
    • 表之间的引用
    • 每张表有多少行被优化器查询

    使用方式如下:

    EXPLAIN +SQL语句

    EXPLAIN SELECT * FROM t1
    

    执行计划包含的信息
    这里写图片描述

    2. 执行计划各字段含义

    2.1 id

    select查询的序列号,包含一组数字,表示查询中执行select子句或操作表的顺序

    id的结果共有3中情况

    • id相同,执行顺序由上至下
      这里写图片描述
      [总结] 加载表的顺序如上图table列所示:t1 t3 t2

    • id不同,如果是子查询,id的序号会递增,id值越大优先级越高,越先被执行

    这里写图片描述

    • id相同不同,同时存在
      这里写图片描述
      如上图所示,在id为1时,table显示的是 <derived2> ,这里指的是指向id为2的表,即t3表的衍生表。

    2.2 select_type

    常见和常用的值有如下几种:
    这里写图片描述
    分别用来表示查询的类型,主要是用于区别普通查询、联合查询、子查询等的复杂查询。

    • SIMPLE 简单的select查询,查询中不包含子查询或者UNION

    • PRIMARY 查询中若包含任何复杂的子部分,最外层查询则被标记为PRIMARY

    • SUBQUERY 在SELECT或WHERE列表中包含了子查询

    • DERIVED 在FROM列表中包含的子查询被标记为DERIVED(衍生),MySQL会递归执行这些子查询,把结果放在临时表

    • UNION 若第二个SELECT出现在UNION之后,则被标记为UNION:若UNION包含在FROM子句的子查询中,外层SELECT将被标记为:DERIVED

    • UNION RESULT 从UNION表获取结果的SELECT

    2.3 table

    指的就是当前执行的表

    2.4 type

    type所显示的是查询使用了哪种类型,type包含的类型包括如下图所示的几种:
    这里写图片描述
    从最好到最差依次是:

    system > const > eq_ref > ref > range > index > all
    

    一般来说,得保证查询至少达到range级别,最好能达到ref。

    • system 表只有一行记录(等于系统表),这是const类型的特列,平时不会出现,这个也可以忽略不计
    • const 表示通过索引一次就找到了,const用于比较primary key 或者unique索引。因为只匹配一行数据,所以很快。如将主键置于where列表中,MySQL就能将该查询转换为一个常量。
      这里写图片描述
      首先进行子查询得到一个结果的d1临时表,子查询条件为id = 1 是常量,所以type是const,id为1的相当于只查询一条记录,所以type为system。
    • eq_ref 唯一性索引扫描,对于每个索引键,表中只有一条记录与之匹配。常见于主键或唯一索引扫描
    • ref 非唯一性索引扫描,返回匹配某个单独值的所有行,本质上也是一种索引访问,它返回所有匹配某个单独值的行,然而,它可能会找到多个符合条件的行,所以他应该属于查找和扫描的混合体。
      这里写图片描述
    • range 只检索给定范围的行,使用一个索引来选择行,key列显示使用了哪个索引,一般就是在你的where语句中出现between、< 、>、in等的查询,这种范围扫描索引比全表扫描要好,因为它只需要开始于索引的某一点,而结束于另一点,不用扫描全部索引。
      这里写图片描述
    • index Full Index Scan,Index与All区别为index类型只遍历索引树。这通常比ALL快,因为索引文件通常比数据文件小。(也就是说虽然all和Index都是读全表,但index是从索引中读取的,而all是从硬盘读取的)
      这里写图片描述
      id是主键,所以存在主键索引
    • all Full Table Scan 将遍历全表以找到匹配的行
      这里写图片描述

    2.5 possible_keys 和 key

    possible_keys 显示可能应用在这张表中的索引,一个或多个。查询涉及到的字段上若存在索引,则该索引将被列出,但不一定被查询实际使用

    key

    • 实际使用的索引,如果为NULL,则没有使用索引。(可能原因包括没有建立索引或索引失效)
      这里写图片描述
    • 查询中若使用了覆盖索引(select 后要查询的字段刚好和创建的索引字段完全相同),则该索引仅出现在key列表中
      这里写图片描述
      这里写图片描述

    2.6 key_len

    表示索引中使用的字节数,可通过该列计算查询中使用的索引的长度,在不损失精确性的情况下,长度越短越好。key_len显示的值为索引字段的最大可能长度,并非实际使用长度,即key_len是根据表定义计算而得,不是通过表内检索出的。
    这里写图片描述

    2.7 ref

    显示索引的那一列被使用了,如果可能的话,最好是一个常数。哪些列或常量被用于查找索引列上的值。
    这里写图片描述

    2.8 rows

    根据表统计信息及索引选用情况,大致估算出找到所需的记录所需要读取的行数,也就是说,用的越少越好
    这里写图片描述

    2.9 Extra

    包含不适合在其他列中显式但十分重要的额外信息

    2.9.1 Using filesort(九死一生)

    说明mysql会对数据使用一个外部的索引排序,而不是按照表内的索引顺序进行读取。MySQL中无法利用索引完成的排序操作称为“文件排序”。
    这里写图片描述

    2.9.2 Using temporary(十死无生)

    使用了用临时表保存中间结果,MySQL在对查询结果排序时使用临时表。常见于排序order by和分组查询group by。
    这里写图片描述

    2.9.3 Using index(发财了)

    表示相应的select操作中使用了覆盖索引(Covering Index),避免访问了表的数据行,效率不错。如果同时出现using where,表明索引被用来执行索引键值的查找;如果没有同时出现using where,表明索引用来读取数据而非执行查找动作。
    这里写图片描述
    这里写图片描述

    2.9.4 Using where

    表明使用了where过滤

    2.9.5 Using join buffer

    表明使用了连接缓存,比如说在查询的时候,多表join的次数非常多,那么将配置文件中的缓冲区的join buffer调大一些。

    2.9.6 impossible where

    where子句的值总是false,不能用来获取任何元组

    SELECT * FROM t_user WHERE id = '1' and id = '2'
    

    2.9.7 select tables optimized away

    在没有GROUPBY子句的情况下,基于索引优化MIN/MAX操作或者对于MyISAM存储引擎优化COUNT(*)操作,不必等到执行阶段再进行计算,查询执行计划生成的阶段即完成优化。

    2.9.8 distinct

    优化distinct操作,在找到第一匹配的元组后即停止找同样值的动作

    3. 实例分析

    这里写图片描述

    • 执行顺序1:select_type为UNION,说明第四个select是UNION里的第二个select,最先执行【select name,id from t2】
    • 执行顺序2:id为3,是整个查询中第三个select的一部分。因查询包含在from中,所以为DERIVED【select id,name from t1 where other_column=’’】
    • 执行顺序3:select列表中的子查询select_type为subquery,为整个查询中的第二个select【select id from t3】
    • 执行顺序4:id列为1,表示是UNION里的第一个select,select_type列的primary表示该查询为外层查询,table列被标记为<derived3>,表示查询结果来自一个衍生表,其中derived3中的3代表该查询衍生自第三个select查询,即id为3的select。【select d1.name …】
    • 执行顺序5:代表从UNION的临时表中读取行的阶段,table列的< union1,4 >表示用第一个和第四个select的结果进行UNION操作。【两个结果union操作】
    展开全文
  • Mysql Explain

    2017-02-28 12:33:15
    Mysql Explain
  • mysql explain

    2015-04-27 10:54:19
    mysql explain
  • MYSQL explain详解

    万次阅读 多人点赞 2013-11-24 17:55:55
    explain显示了mysql如何使用索引来处理select语句以及连接表。可以帮助选择更好的索引和写出更优化的查询语句。

    explain显示了mysql如何使用索引来处理select语句以及连接表。可以帮助选择更好的索引和写出更优化的查询语句。

    虽然这篇文章我写的很长,但看起来真的不会困啊,真的都是干货啊!!!!

    先解析一条sql语句,看出现什么内容

    EXPLAIN SELECT s.uid,s.username,s.name,f.email,f.mobile,f.phone,f.postalcode,f.address
    FROM uchome_space AS s,uchome_spacefield AS f
    WHERE 1
    AND s.groupid=0
    AND s.uid=f.uid

    1. id

    SELECT识别符。这是SELECT查询序列号。这个不重要,查询序号即为sql语句执行的顺序,看下面这条sql

    EXPLAINSELECT *FROM (SELECT* FROMuchome_space LIMIT 10)AS s

    它的执行结果为


    可以看到这时的id变化了

    2.select_type

    select类型,它有以下几种值

    2.1 simple 它表示简单的select,没有union和子查询

    2.2 primary 最外面的select,在有子查询的语句中,最外面的select查询就是primary,上图中就是这样

    2.3 union union语句的第二个或者说是后面那一个.现执行一条语句,explain
    select  *  from uchome_space limit 10 union select * from uchome_space limit 10,10

    会有如下结果

    第二条语句使用了union

    2.4 dependent union    UNION中的第二个或后面的SELECT语句,取决于外面的查询

    2.5 union result        UNION的结果,如上面所示

    还有几个参数,这里就不说了,不重要

    3 table

    输出的行所用的表,这个参数显而易见,容易理解

    4 type

    连接类型。有多个参数,先从最佳类型到最差类型介绍 重要且困难

    4.1 system

    表仅有一行,这是const类型的特列,平时不会出现,这个也可以忽略不计

    4.2 const

    表最多有一个匹配行,const用于比较primary key 或者unique索引。因为只匹配一行数据,所以很快

    记住一定是用到primary key 或者unique,并且只检索出两条数据的 情况下才会是const,看下面这条语句

    explain SELECT * FROM `asj_admin_log` limit 1,结果是

    虽然只搜索一条数据,但是因为没有用到指定的索引,所以不会使用const.继续看下面这个

    explain SELECT * FROM `asj_admin_log` where log_id = 111

    log_id是主键,所以使用了const。所以说可以理解为const是最优化的

    4.3 eq_ref

    对于eq_ref的解释,mysql手册是这样说的:"对于每个来自于前面的表的行组合,从该表中读取一行。这可能是最好的联接类型,除了const类型。它用在一个索引的所有部分被联接使用并且索引是UNIQUEPRIMARY KEY"。eq_ref可以用于使用=比较带索引的列。看下面的语句

    explain select * from uchome_spacefield,uchome_space where uchome_spacefield.uid = uchome_space.uid

    得到的结果是下图所示。很明显,mysql使用eq_ref联接来处理uchome_space表。

    目前的疑问:

           4.3.1 为什么是只有uchome_space一个表用到了eq_ref,并且sql语句如果变成

           explain select * from uchome_space,uchome_spacefield where uchome_space.uid = uchome_spacefield.uid

           结果还是一样,需要说明的是uid在这两个表中都是primary

    4.4 ref 对于每个来自于前面的表的行组合,所有有匹配索引值的行将从这张表中读取。如果联接只使用键的最左边的前缀,或如果键不是UNIQUEPRIMARY KEY(换句话说,如果联接不能基于关键字选择单个行的话),则使用ref。如果使用的键仅仅匹配少量行,该联接类型是不错的。

    看下面这条语句 explain select * from uchome_space where uchome_space.friendnum = 0,得到结果如下,这条语句能搜出1w条数据


    4.5 ref_or_null 该联接类型如同ref,但是添加了MySQL可以专门搜索包含NULL值的行。在解决子查询中经常使用该联接类型的优化。

    上面这五种情况都是很理想的索引使用情况

    4.6 index_merge 该联接类型表示使用了索引合并优化方法。在这种情况下,key列包含了使用的索引的清单,key_len包含了使用的索引的最长的关键元素。

    4.7 unique_subquery 

    4.8 index_subquery

    4.9 range 给定范围内的检索,使用一个索引来检查行。看下面两条语句

    explain select * from uchome_space where uid in (1,2)

    explain select * from uchome_space where groupid in (1,2)

    uid有索引,groupid没有索引,结果是第一条语句的联接类型是range,第二个是ALL.以为是一定范围所以说像 between也可以这种联接,很明显

    explain select * from uchome_space where friendnum = 17

    这样的语句是不会使用range的,它会使用更好的联接类型就是上面介绍的ref

    4.10 index     该联接类型与ALL相同,除了只有索引树被扫描。这通常比ALL快,因为索引文件通常比数据文件小。(也就是说虽然all和Index都是读全表,但index是从索引中读取的,而all是从硬盘中读的)

    当查询只使用作为单索引一部分的列时,MySQL可以使用该联接类型。

    4.11  ALL  对于每个来自于先前的表的行组合,进行完整的表扫描。如果表是第一个没标记const的表,这通常不好,并且通常在它情况下差。通常可以增加更多的索引而不要使用ALL,使得行能基于前面的表中的常数值或列值被检索出。

    5 possible_keys 提示使用哪个索引会在该表中找到行,不太重要

    6 keys MYSQL使用的索引,简单且重要

    7 key_len MYSQL使用的索引长度

    8 ref   ref列显示使用哪个列或常数与key一起从表中选择行。

    9 rows 显示MYSQL执行查询的行数,简单且重要,数值越大越不好,说明没有用好索引

    10 Extra  该列包含MySQL解决查询的详细信息。

    10.1 Distinct     MySQL发现第1个匹配行后,停止为当前的行组合搜索更多的行。一直没见过这个值

    10.2 Not exists 

    10.3 range checked for each record

    没有找到合适的索引

    10.4 using filesort   

    MYSQL手册是这么解释的“MySQL需要额外的一次传递,以找出如何按排序顺序检索行。通过根据联接类型浏览所有行并为所有匹配WHERE子句的行保存排序关键字和行的指针来完成排序。然后关键字被排序,并按排序顺序检索行。”目前不太明白

    我的理解:如果存在排序并且取出的列包括text类型会使用到using filesort,这会非常慢

    10.5 using index 只使用索引树中的信息而不需要进一步搜索读取实际的行来检索表中的信息。这个比较容易理解,就是说明是否使用了索引

    explain select * from ucspace_uchome where uid = 1的extra为using index(uid建有索引)

    explain select count(*) from uchome_space where groupid=1 的extra为using where(groupid未建立索引)

    10.6 using temporary

    为了解决查询,MySQL需要创建一个临时表来容纳结果。典型情况如查询包含可以按不同情况列出列的GROUP BYORDER BY子句时。

    出现using temporary就说明语句需要优化了,举个例子来说

    EXPLAIN SELECT ads.id FROM ads, city WHERE   city.city_id = 8005   AND ads.status = 'online'   AND city.ads_id=ads.id ORDER BY ads.id desc

    id  select_type  table   type    possible_keys   key      key_len  ref                     rows  filtered  Extra                          
    ------  -----------  ------  ------  --------------  -------  -------  --------------------  ------  --------  -------------------------------
         1  SIMPLE       city   ref     ads_id,city_id  city_id  4        const                   2838    100.00 Using temporary; Using filesort
         1  SIMPLE       ads     eq_ref  PRIMARY         PRIMARY  4        city.ads_id       1    100.00  Using where   

    这条语句会使用using temporary,而下面这条语句则不会

    EXPLAIN SELECT ads.id FROM ads, city WHERE   city.city_id = 8005   AND ads.status = 'online'   AND city.ads_id=ads.id ORDER BYcity.ads_id desc

    id  select_type  table   type    possible_keys   key      key_len  ref                     rows  filtered  Extra                      
    ------  -----------  ------  ------  --------------  -------  -------  --------------------  ------  --------  ---------------------------
         1  SIMPLE       city   ref     ads_id,city_id  city_id  4        const                   2838    100.00 Using where; Using filesort
         1  SIMPLE       ads    eq_ref  PRIMARY         PRIMARY  4        city.ads_id       1    100.00  Using where   

    这是为什么呢?他俩之间只是一个order by不同,MySQL 表关联的算法是 Nest Loop Join,是通过驱动表的结果集作为循环基础数据,然后一条一条地通过该结果集中的数据作为过滤条件到下一个表中查询数据,然后合并结果。EXPLAIN 结果中,第一行出现的表就是驱动表(Important!)以上两个查询语句,驱动表都是 city,如上面的执行计划所示!

    对驱动表可以直接排序,对非驱动表(的字段排序)需要对循环查询的合并结果(临时表)进行排序(Important!)
    因此,order by ads.id desc 时,就要先 using temporary 了!
    驱动表的定义
    wwh999 在 2006年总结说,当进行多表连接查询时, [驱动表] 的定义为:
    1)指定了联接条件时,满足查询条件的记录行数少的表为[驱动表];
    2)未指定联接条件时,行数少的表为[驱动表](Important!)。
    永远用小结果集驱动大结果集

    今天学到了一个很重要的一点:当不确定是用哪种类型的join时,让mysql优化器自动去判断,我们只需写select * from t1,t2 where t1.field = t2.field

    通俗解释:select  * from table order by field

    其中filed建普通索引,这种情况会使用到using temporary,因为虽然这时候使用到了索引,但因为扫描的是全表,mysql优化器会判断:反正是搜索全表而且要排序,因为这时候要回行,我还不如不沿着索引找数据,直接全部检索出所有数据来在排序。如果语句这么写 select * from table where field > 1 order by field.mysql优化器就会这么判断:这时候不是搜全表,我需要先根据where条件,沿着索引树搜出想要的相应索引数据,在回行(一边找索引一边回行)。这时候就不需要临时表了

    10.7 using where

    WHERE子句用于限制哪一个行匹配下一个表或发送到客户。除非你专门从表中索取或检查所有行,如果Extra值不为Using where并且表联接类型为ALLindex,查询可能会有一些错误。(这个说明不是很理解,因为很多很多语句都会有where条件,而type为all或index只能说明检索的数据多,并不能说明错误,useing where不是很重要,但是很常见)

    如果想要使查询尽可能快,应找出Using filesort Using temporaryExtra值。

    10.8 Using sort_union(...), Using union(...),Using intersect(...)

    这些函数说明如何为index_merge联接类型合并索引扫描

    10.9 Using index for group-by

    类似于访问表的Using index方式,Using index for group-by表示MySQL发现了一个索引,可以用来查询GROUP BYDISTINCT查询的所有列,而不要额外搜索硬盘访问实际的表。并且,按最有效的方式使用索引,以便对于每个组,只读取少量索引条目。

    实例讲解


    通过相乘EXPLAIN输出的rows列的所有值,你能得到一个关于一个联接如何的提示。这应该粗略地告诉你MySQL必须检查多少行以执行查询。当你使用max_join_size变量限制查询时,也用这个乘积来确定执行哪个多表SELECT语句。



    2017年1.26的拓展      我是无所不能的coder的分界线

    回头看看几年前写的这篇博客,真的也是很浅显,只是简单的介绍了explain后每个选项的概念,对于实例没有太多的讲解,而且最重要的是没有指出那种情况下的选项(结合实际情况)才是最优化的,ok,start again

    很明显,在所有explain的结果中最重要的要数type/key/rows/extra这4个字段了,那接下来我着重在说一下这四个字段代表的意思及如何优化

    现有两个表,一个项目表(project),一个留言表(t_message),用户可以针对不同的项目进行流行操作。

    现有一个最基本的联表操作,

    EXPLAIN SELECT * FROM project AS p JOIN jmw_message.t_message AS t ON p.id = t.target_id
    结果是这样的

    出现这种情况是最容易理解的了,因为这只是简单联表查询,没有加任何条件,在实际情况下是不会出现这种sql的。从上图的结果中可以看出mysql对t_message表进行了全表扫描,对project表使用了eq_ref,这符合了mysql对什么情况下会使用到eq_ref的定义,这是非常理想的一种连接类型。

    下面我们讨论一个实际情况下会遇到的例子,我们联表取前100条数据,
    EXPLAIN SELECT * FROM project AS p JOIN jmw_message.t_message AS t ON p.id = t.target_id LIMIT 100


    可以发现,除了影响的行数稍微多了一点(可以忽略,甚至可以理解为没有不同),其他所有的参数都是相同的,也就是说,这种情况下搜索全部数据和搜索100条数据的耗时是一样的,为什么会这样呢?不应该啊!!

    这里需要着重说明的是:上面两条语句explain得到的结果是相同的,是因为他们的索引使用策略是相同的,即都没有很好的使用索引,(因为没有where条件和order by语句)但他们的最终耗时是不同的,很明显传输100条数据肯定要比传送1条数据慢。所以,最终耗时会在sending data(用show profile查看)上消耗的比例最大

    那实际情况下,最有可能会遇到什么问题呢?

    1 根据项目id作为搜索条件(即使用where条件)

    2 根据时间或者id来排序(即使用order by条件)

    3 根据以上两个

    下面我们开始举栗子

    《1》搜索最新的100条留言

    《2》搜索出某个项目下最新的10条留言

    《3》搜索出某个项目最近一个月每天有多少条留言

    《4》搜索出最近一个月每天有多少条留言

    《5》搜索某个用户今天留言数量

    《6》搜索今天有多少条新增留言

    下面我们开始吃栗子

    《1》搜索最新的100条留言

              EXPLAIN SELECT * FROM project AS p JOIN jmw_message.t_message AS t ON p.id = t.target_id ORDER BY t.id DESC LIMIT 100 ;
              EXPLAIN SELECT * FROM project AS p JOIN jmw_message.t_message AS t ON p.id = t.target_id ORDER BY p.id DESC LIMIT 100

    以下两条语句都能实现效果,但索引使用情况却完全不同。第一条语句要比第二条优化的多,



    可以看到,第一条语句的type值为index,影响结果即只有100行,也就是说非常合适的使用了索引。正所谓,福无双至祸不单行,当你一个地方出问题的时候,难免其他地方也出问题,因为没有使用合理的索引-->导致全表扫描-->影响结果集太大-->从而导致使用了using temporary和using filesort(这个也很重要)。那这两条语句很明显只有order by条件的一点小小的不同.说实话,我不是很理解为什么会出现这种情况因为这两个条件分表是两个表的主键,都有主键索引,唯一合理的解释可能是因为这时候联表之后t_message是主表(因为他是留言表,一切以他为准),而order by排序当然应该是根据主表的主键拍排序才会使用到索引了,似乎有点牵强,但貌似这么理解没有大毛病

    下面着重说一下using temporary和using filesort

    using temporary 官方解释:”为了解决查询,MySQL需要创建一个临时表来容纳结果。典型情况如查询包含可以按不同情况列出列的GROUP BYORDER BY子句时。“”很明显就是通过where条件一次性检索出来的结果集太大了,内存放不下了,只能通过家里临时表来辅助处理

    using filesort 官方解释:“MySQL需要额外的一次传递,以找出如何按排序顺序检索行。通过根据联接类型浏览所有行并为所有匹配WHERE子句的行保存排序关键字和行的指针来完成排序。然后关键字被排序,并按排序顺序检索行”

    我这里的理解是:对于order by的字段没有使用到字段,所以使用了using filesort.   这两个问题同时出现的可能性很大啊!!!

    《2》搜索出某个项目下最新的10条留言

    EXPLAIN SELECT * FROM t_message WHERE target_id = 770 ORDER BY id DESC LIMIT 10;
    EXPLAIN SELECT * FROM t_message WHERE target_id = 770 ORDER BY publish_time DESC LIMIT 10

    以上两条select语句的执行搜索结果是一样的,但explain分析结果不同,只是因为order by 条件的不同








    展开全文
  • explain 之key explain 之 rows 扫描行的数量 explain 之 extra
  • explain详解

    千次阅读 2020-08-24 22:17:30
    使用explain可以模拟优化器执行sql语句,分析查询语句的结构,是否使用索引等等 使用方法: 在查询语句select关键字前面加上explain关键字,如下图的格式,然后就会返回分析的结果 下面来详解使用explain后返回的...
  • mysql explain可以帮助你检查索引和更好的优化查询语句,今天特地学习了下mysql explain的用法,需要的朋友可以参考下
  • 数据库 explain详解

    2020-12-14 18:03:57
    文章目录数据库 explain详解1、什么是explain2、explain有什么用3、explain个字段详解3.1 id详解3.2 select_type 详解3.3 table 详解3.4 type 详解3.5 possible_keys3.6 key3.7 key_len3.8 ref3.9 rows3.10 extra4、...
  • Explain详解

    千次阅读 2020-02-01 16:05:56
    二、explain 的两种使用方式 三、explain中的列 1. id列 2. select_type列 3. table列 4. type列 5. possible_keys列 6. key列 7. key_len列 8. ref列 9. rows列 10. Extra列 四、索引最佳实践 使用...
  • explain语句

    2019-11-15 20:26:40
    explain(解释)语句 使用explain关键字可以模拟优化器执行sql查询语句,从而知道mysql是如何处理你的sql语句的,这可以帮你分析你的查询语句或是表结构的性能瓶颈,通过explain命令可以得到: 1.表的读取顺序 2.数据读取...
  • MySQL-Explain

    2016-08-09 15:05:54
    Mysql Explain 使用
  • PostgreSQL EXPLAIN

    2020-12-30 09:54:23
    本文学习如何使用PostgreSQL EXPLAIN语句分析SQL执行计划。 1. PostgreSQL EXPLAIN语句 EXPLAIN语句返回给定SQL语句的PostgreSQL分析引擎生成的执行计划。展示语句中涉及的表如何被索引扫描或顺序扫描等,如果使用多...
  • Mariadb EXPLAIN

    2018-10-02 11:05:41
    MariadDB 查询中可以使用SELECT的前面使用EXPLAIN来查看索引的使用情况,接下来,我们来描述一下,explain所产生的一些信息。 EXPLAIN SELECT clause; 获取查询执行计划信息,用来查看查询优化器如何执行查询 ...
  • Mysql Explain 详细介绍

    2020-09-09 23:14:36
    主要介绍了Mysql Explain 详细介绍的相关资料,这里对Mysql Explain 的语法,属性,以及如何使用,做了全面介绍,需要的朋友可以参考下
  • explain 之 table 展示这一行的数据是关于哪一张表的 explain 之 type
  • explain记录

    千次阅读 2020-09-25 15:18:52
    EXPLAIN简介 使用EXPLAIN关键字可以模拟优化器执行SQL查询语句,从而知道MySQL是如何处理你的SQL语句的。分析你的查询语句或是表结构的性能瓶颈。 通过explain我们可以获得以下信息: 表的读取顺序 数据读取操作的...
  • Explain语法

    2020-08-24 15:57:27
    1. EXPLAIN EXTENDED SELECT …… 将执行计划“反编译”成SELECT语句,运行SHOW WARNINGS 可得到被MySQL优化器优化后的查询语句 2. EXPLAIN PARTITIONS SELECT …… 用于分区表的EXPLAIN 执行计划包含的信息
  • Mysql调优:第一章:Explain详解

    千次阅读 多人点赞 2020-12-29 13:46:26
    Mysql调优:第一章:Explain详解与索引Explain是什么?有什么作用?explain 两个变种explain extended:explain partitions:explain中的列索引最佳实践 Explain是什么?有什么作用? Explain是MySQL的关键字,显示...
  • EXPLAIN Statement

    2019-12-11 11:57:30
    Reference: https://dev.mysql.com/doc/refman/8.0/en/explain.html https://dev.mysql.com/doc/refman/8.0/en/explain-output.html 1、Obtaining Table Structure ...DESCRIBE|EXPLAIN order_tm_order...
  • Mysql explain

    2019-04-11 11:39:37
    explain来获取关于查询执行计划的信息。比如mysql中有慢查询语句,可以通过explian来返回其执行计划中的信息,还可以获得很多可能被优化器考虑到的访问策略的细节,以及当运行SQL语句时哪种策略预计会被优化器采用...
  • EXPLAIN详解

    千次阅读 2021-03-21 18:32:30
    EXPLAIN语句可以让我们查看某个语句的具体执行计划。 列名 描述 id 在一个大的查询语句中,每个SELECT关键字都对应一个唯一的id select_type SELECT关键字对应的查询的类型 table 表名 partitions ...
  • SQL-explain

    2020-08-07 13:23:06
    什么是explain? 使用explain关键字可以模拟优化器执行SQL查询语句,从而了解MYSQL是如何处理SQL语句 explain的作用 我们使用explain关键字可以知道以下内容: 表的读取顺序 数据读取操作的操作类型 哪些索引被使用 ...
  • MongoDB Explain

    千次阅读 2016-11-15 19:40:24
    MongoDB提供了db.collection.explain()方法, cursor.explain()方法, 和explain命令去返回查询计划信息和查询计划的执行统计信息。explain结果中呈现的查询计划可以看做一个阶段树。每个阶段将其结果(即文档或索引键...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 164,281
精华内容 65,712
关键字:

explain