在NoSQL横行的时代,传统关系型数据库也还是有占据它的一席之位。MySQL 的市场份额还是很大的。

据了解到的MySQL版本已经到5.7.20+了。目前本人服务器上的还没有这么高。只在5.5+的版本上

浅谈MySQL 之 EXPLAIN

说到MySQL免不了要提到的是 它的执行计划,EXPLAIN 关键字可以模拟优化器执行SQL查询语句,从而知道MySQL是如何处理SQL语句的。

浅谈MySQL 之 EXPLAIN

查询语句前加上 EXPLAIN 关键字,执行后得到一个类似以上的结果集。 现对结果集各列做如下说明

id 列 通常和select_type 列一起 做参考如下结构

id      select_type

1        SIMPLE

2        PRIMARY

3        SUBQUERY

4        DERIVED

5        UNION

6        UNIONRESULT

如果  id 相同  ,执行顺序由上而下

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

select_type 列   表示查询的类型 区分普通查询,联合查询,子查询等

    1.SIMPLE  简单的select查询,查询中不包含子查询或者union  如实例上

    2. PRIMARY   查询中包含子部分,最外层查询被标记为PRIMARY

    3. SUBQUERY 在SELECT 或WHERE列表中包含子查询   如下示例中

浅谈MySQL 之 EXPLAIN

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

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

    6.UNION RESULT 从UNION表获取结果的SELECT  如下示例

浅谈MySQL 之 EXPLAIN


table 列   显而易见的就是指涉及到的哪张表

type 列 表示查询使用到什么类型的索引 通常包括

    system>const>eq_ref>ref>range>index >ALL    最好到最差, ALL即为全表扫描

    system:    表只有一条记录,是const类型的特例

    const :      通过索引一次就找到,const 用于 primary key 或者 unique索引,如通过主键查询。

   eq_ref:   唯一性索引扫描    对于每个索引键,表中就一条记录与之匹配。场景用主键扫描或者唯一键扫描

   ref :     非唯一性索引扫描,返回某个单独值的所有行。本质上也是一种索引访问。返回所有匹配某个单独的行,可能找到很多 符合条件的记录行

    range:   只检索给定范围的行,使用一个索引。key列显示使用了哪个索引,一般来书就是咋where语句中对索引between,    <,> in 等查询操作。这种扫描索引范围比全表扫描要好,在索引的范围区间扫描,不用扫描全部。

    index:    Full Index Scan  index 与ALL的区别为index类型只遍历索引树,通常比ALL快。因为索引文件比数据文件小

    all :      Full  Table Scan  将遍历全表找到符合的记录行

通常保证查询达到range 级别,最好能达到ref了    以下将建表模拟以上提到的索引查询情况

浅谈MySQL 之 EXPLAIN


浅谈MySQL 之 EXPLAIN


浅谈MySQL 之 EXPLAIN


浅谈MySQL 之 EXPLAIN


浅谈MySQL 之 EXPLAIN


浅谈MySQL 之 EXPLAIN


possible_keys列:    显示可能应用在查询时的索引列,一个或者多个 ,但实际可能没有用到索引列

key 列:   实际查询中用到的索引列,对比possible_keys,可能知道实际有没有使用到索引列

key_len 列:  表示索引列中使用的字节数,可通过该列计算查询中使用的索引的长度。在不损失精度的情况下,长度越短越好

    key_len显示的值为索引字段的最大可能长度,并非实际使用长度。

ref列:    显示索引的哪一列被使用了,可能的话会是一个常数()哪些列或者常量被用于查找索引列上的值

rows 列 根据表统计信息及索引选用情况,大致估算出找到所需的记录所需读取的行数

Extra 列:包含不适合在其他列中显示但十分重要的额外信息,通常包括以下

    using filesort  说明mysql会对数据使用一个外部的索引排序,而不是按照表内的索引排序,MYSQL中无法利用

索引完成的排序操作称为"文件排序"  如下示例(没有合适使用索引导致)

浅谈MySQL 之 EXPLAIN

        Using temporary   使用了临时表保存中间结果,MySQL在对查询结果排序时使用了临时表。常见于排序order by 和分组查询 group by  ,如下示例(没有合适使用索引导致)

浅谈MySQL 之 EXPLAIN

        Using index    表示相应的select语句中使用了覆盖索引,避免了访问表的数据行,如果同时出现了using where 表明索引同时用来执行索引键值的查找,如果没有同时出现则表示索引用来读取数据而非执行查找动作。 如下两个示例说明这两个情况

浅谈MySQL 之 EXPLAIN


浅谈MySQL 之 EXPLAIN


using where   比较常见 表明使用了where 过滤

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

浅谈MySQL 之 EXPLAIN


using join buffer        使用了连接缓存

select tables optimized away    在没有Group by 子句的情况下基于索引优化MIN/Max操作或者对于MyIsam 存储引擎优化count(*)操作,不必等到执行阶段再做计算,在执行计划生成的阶段即完成优化工作

浅谈MySQL 之 EXPLAIN

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

浅谈MySQL 之 EXPLAIN


以上是简单说明了下 通过执行计划信息的查看便于我们发现SQL查询的瓶颈,通过建立合适的索引 来优化SQL语句。以上的示例有存在索引失效的情况,建立了相关索引列且在索引列上也参与了查询但执行计划的type 列显示还是ALL的问题。下一篇将会介绍如何选取合适的列作为索引列,以及什么情况下索引会失效。


相关文章: