查询计划参数详解

explain这是此次想要了解的重点命令,用于查看mysql中查询sql语句的执行计划,用来对sql进行优化,以最合理的方式写sql语句
一条标准的sql查询语句:mysql

explain select id from user_customer where id=1\G;

获得的结果:sql

*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: user_customer
   partitions: NULL
         type: const
possible_keys: PRIMARY
          key: PRIMARY
      key_len: 4
          ref: const
         rows: 1
     filtered: 100.00
        Extra: Using index

从上面能够看到全部的参数,下面一一进行说明:服务器

id

select查询的标识符,每一个select都会被自动分配一个惟一的标识符mysql优化

select_type

select 查询的类型,常见的值以下:性能

  • SIMPLE:表示此查询不包含UNION查询或子查询优化

  • PRIMARY:表示此查询是最外层的查询ui

  • UNION:表示此查询是UNION的第二或随后的查询编码

  • DEPENDENT UNION:UNION中的第二个或后面的查询语句,取决于外面的查询code

  • UNION RESULT:UNION的结果排序

  • SUBQUERY:子查询中的第一个SELECT

  • DEPENDEND SUBQUERY:子查询中的第一个SELECT,取决于外面的查询,即子查询依赖于外层查询的结果

  • DERIVED:被驱动的select子查询(子查询位于FROM子句)

  • MATERIALIZED:被物化的子查询

table

查询涉及到的数据表或衍生表

type

type字段比较重要,它标识了查询是否高效,是使用了全表扫描仍是索引扫描等等

  • system:表中只有一条数据,这个类型是特殊的const类型

  • const:针对主键或惟一索引的等值查询扫描,最多只返回一条数据。const查询的速度很是快,由于它仅仅读取一次便可,以下面的sql语句

select * from user_customer where id=5;
  • ref:此类型一般出如今多表的join查询,针对于非惟一或非主键索引,或者是使用了最左前缀规则索引的查询

select * from user_customer where first_name='123' and last_name='456';

explain select * from migrations,user_customer  where migrations.batch=user_customer.uid and cid>1\G;

eq_ref:一般出如今多表的join查询,对于对于前表的每个结果,都只能匹配到后表的一行结果,而且查询的比较操做是=,查询效率较高

explain select * from migrations,user_customer  where migrations.batch=user_customer.uid \G;    //前表的数据在后表中都有匹配
  • range:range表示的索引范围查找,经过索引字段范围获取表中部分数据记录,这个类型一般出如今=, <>, >, <, between, in()等操做中
    typerange时,那么explain输出的ref字段为NULL,而且ken_len字段为这次查询中使用到的索引的最长的那个

    > int的长度是4字节,bigint的长度是8字节;字符串根据字段的长度能够计算出长度(**utf每一个字符占用3字节,若是是varchar**);若是字段容许null则会增长一个字节的大小
  • index:表示扫描的时候仅仅扫描了索引,而不扫描数据;也就是说在查询数据的时候直接在索引树中就能够获取到,在这种状况下的时候,extra字段会显式Using Index

  • all:表示全表扫描,是全部这些属性中性能最差的一个

type类型的性能比较

all < index < range ~ index_merge < ref < eq_ref < const < system

possible_keys

表示在查询的过程当中有可能使用到的keys

ken_len

表示查询优化器使用到了的索引的字节数,这个字段能够评估出组合索引是否被彻底使用到,或只有最左部分字段被使用到,key_len的计算规则以下:

  • 字符串

    • char(n):固定长度,n字符长度,根据不一样的编码n2或n3的字节

    • varchar(n):变长长度,在实际计算存储大小的时候,n小于255则用1字节存储长度,大于255则用2字节存储长度

  • 数值类型

    • tinyint(n):1字节

    • smallint(n):2字节

    • mediumint(n):3字节

    • int(n):4字节

    • bitint(n):8字节

  • 时间类型

    • date:3字节

    • timestamp:4字节

    • datetime:8字节

  • 字段属性:

    • Null属性占用一个字节,若是字段是NOT NULL的,则不会占用这额外的一字节

    • 在数值类型中,是预留出了一位去存储数值的符号

rows

mysql查询优化器根据统计信息,估算sql要查找结果集须要扫描读取的数据行数,这个值能够直观的反映出sql的效率,原则上rows数值越小越好

extra

在sql中不少额外的信息会在extra字段中体现:

  • Using filesort
    当Extra字段中有Using filesort时,表示mysql须要额外的排序操做,不能经过索引顺序达到排序效果;在sql语句中使用order by 进行排序的时候,若是没有很好的使用到定值和最左排序的话,会出现这种状况

  • Using index condition

    • 这是mysql5.6的新特性,叫索引条件推送,只是针对于二级索引。

    • 在通常状况下,mysql服务器都会将存储引擎处理完成的数据返回给服务层后在应用where条件进行过滤,可是当mysql筛选到where条件中的第一个条件筛选的方式是相似于范围查询,就是like<等;可是这里mysql的查询优化器会筛选第一个where条件中的可以查询出的范围,会根据range的范围与数据的总数进行对比进行什么样的查询

    • 查询想要获取的字段都是*

  • Using index
    “覆盖索引扫描”,表示查询在索引树上就能够找到所须要的数据,而不须要扫描底层的叶子节点数据,这种状况性能很好

只出现了这个的时候表示性能很好;若是这个和Using where同时出现的话,表示先在存储引擎中使用索引进行筛选,再在mysql服务中进行条件筛选

  • Using temporary
    在查询的时候使用临时表,通常出现排序,分组和多表join的状况,查询效率不高,建议进行优化

  • Using where
    使用了where从句来限制哪些行将与下一个表匹配或者是返回给用户

Extra列出现Using where表示mysql服务器将存储引擎返回服务层之后再应用where条件过滤
有一种状况,数据表中数据量很大,查询的条件在数据表中占的比例也很高,原本在原则上可使用索引,可是由于该查询记录占表中比例很大,mysql会不对该sql使用索引,这种状况能够在查询语句后面使用limit进行限制

  • Using MRR
    这也是mysql5.6新增的特性, Multi-Range Read(多范围读),针对基于辅助/第二索引的查询,减小随机IO,而且将随机IO转换为顺序IO,提升查询效率

在基于mysql中的Innodb的数据存储方式才用的是B+tree,二级索引的存储顺序与主键的顺序是不一致的,开启了mrr以后,mysql将根据辅助结果集获取的结果集根据主键进行排序,将乱序化为有序,能够用主键访问基表,将随机读转换为顺序读,多页数据记录可一次性读入或根据这次的主键范围分次读入,以减小IO操做,提升查询效率

  • Not exists
    mysql优化了left join,一旦它找到了匹配left join标准的行,就再也不搜索了

相关文章
相关标签/搜索