导航

explain

Posted on 2017-12-22 20:37  耍流氓的兔兔  阅读(283)  评论(0编辑  收藏  举报

 

参考博客:http://blog.csdn.net/zhuxineli/article/details/14455029

什么是explain:

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

入门:

  先解析一条sql语句:

SELECT * FROM tb_user

对表中字段进行分析:

  id:select识别符,是select查询序列号,即为sql语句执行的顺序

  select_type:select类型,有以下几种值:

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

    primary:最外面的select,在有子查询的语句中,最外面的select查询就是primary

    union:union语句的第二个或者说是后面那一个

    dependent union:union语句中的第二个或后面的select语句,取决于外面的查询

    union result:union的结果

  解析一条sql语句:

EXPLAIN SELECT * FROM (SELECT * FROM tb_user LIMIT 0,10) AS u

  再解析一条sql语句:

EXPLAIN SELECT * FROM tb_user LIMIT 0,10 
    UNION
    SELECT * FROM tb_user LIMIT 0,10 

 

  table:这一行的数据是哪张表的

  type:显示连接使用了何种类型,有多个参数,先从最佳类型到最差类型介绍,重要而且困难

    system:表仅有一行,这是const类型的特例,平时不会出现

    const:表最多有一个匹配行,const用于比较primary key或者unique索引,因为只匹配一行数据,所以记住一定是用到primary key或者unique,并且只检索出一条数据的情况下才会是const,所以可以理解为const是最优化的

    eq_ref:对于每个来自前面的表的行组合,从该表中读取一行,这可能是最好的联接类型,除了const类型,它用在一个索引的所有部分被联接使用并且索引是UNIQUE或PRIMARY KEY

        eq_ref可以用于使用=比较带索引的列

    ref:这个连接类型只有在查询使用了不是惟一或主键的键或者是这些类型的部分(比如,利用最左边前缀)时发生。对于之前的表的每一个行联合,全部记录都将从表中读出。这个类型严重依赖于根据索引匹配的记录多少—越少越好 

    range:这个连接类型使用索引返回一个范围内的行,比如使用>或<查找东西时发生的情况

    indexhe:这个连接类型对前面的表中的每一个记录联合进行完全扫描(比ALL好,因为索引一般小于表数据)

    ALL:这个连接类型对于前面的每一个记录联合进行完全扫描,这一般比较糟糕,应该尽量避免

   解析一条sql语句:

EXPLAIN SELECT * FROM tb_user WHERE id = 1

EXPLAIN SELECT * FROM blog b, author a WHERE b.`author_id` = a.`id`

EXPLAIN SELECT * FROM ar_user u, ar_role r WHERE u.`rid` = r.`rid`

疑问:为什么只有在ar_role表中使用eq_ref,并且sql变为
  EXPLAIN SELECT * FROM ar_role r , ar_user u WHERE u.`rid` = r.`rid`
结果还是一样???

  possible_keys:显示可能应用在这张表中的索引,如果为空,没有可能的索引,可以为相关的域从where语句中选择一个合适的语句

  key:实际使用的索引,如果为null,没有使用索引,很少的情况下,MySql会选择优化不足的索引,在这种情况下,可以在select语句中使用use index(indexname)来强制使用一个索引或者使用ingnore index(indexname)来强制MySql忽略索引

    key_len:使用的索引的长度,在不损失精确性的情况下,长度越短越好

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

  rows:MySql认为必须检查的用来返回请求数据的行数

  Extra:关于MySql如何解析查询的额外信息

    only index:信息只用索引树中的信息检索出来的,这个比扫描整个表要快

    where userd:使用上了where限制

    impossible where:表示用不着where,一般就是没查出来

    using filesort/ using temprorary的话会很很吃力,where和order by的索引经常无法兼顾,如果按照where来确定索引,那么在order by时,就必然会引起using filesort,这就是要看先过滤再排序划算,还是先排序再过滤划算