近期有个产品的统计信息超过了2000万行,后台的查询直接超时了,单纯sql在命令行执行都须要20s以上。用EXPLAIN后发现由于索引太多这条SQL没有用上计划的索引,更改后直接秒级出结果,下面看看EXPLAIN(Navicat里的解释按钮一样效果)的威力。
explain执行后的效果大体以下:html
mysql> explain select * from student where classid=1; +----+-------------+---------+------------+------+---------------+------+---------+------+------+----------+-------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+---------+------------+------+---------------+------+---------+------+------+----------+-------------+ | 1 | SIMPLE | student | NULL | ALL | NULL | NULL | NULL | NULL | 4 | 25.00 | Using where | +----+-------------+---------+------------+------+---------------+------+---------+------+------+----------+-------------+ 1 row in set, 1 warning (0.00 sec)
总共有12列,分别是id、select_type、table、partitions、type、possible_keys、key、key_len、ref、rows、filtered、Extra,其中在我看来最重要的是key列和extra列。
key直接显示有没有使用索引,extra显示是否根据条件查询、有没有利用文件排序等。
可以把SQL优化(修改)到使用索引基本上就能够通吃绝大多数状况了。mysql
列名 | 解释 |
---|---|
id | 查询的惟一标识 |
select_type | 查询类型 |
table | 查询的那个表 |
partitions | 匹配的分区 |
type | join类型 |
possible_keys | 可能使用的索引 |
key | 最终使用的索引 |
key_len | 最终使用的索引的长度 |
ref | 与索引一块儿被使用的字段或常数 |
rows | 查询扫描的行数,是个估算值 |
filtered | 查询条件所过滤的数据的百分比 |
Extra | 额外的信息 |
查询的惟一标识,当这行是联合查询中的被驱动的表时这个值是Null。web
值 | 解释 |
---|---|
SIMPLE | 表示此查询不包含 UNION 查询或子查询 |
PRIMARY | 表示此查询是最外层的查询 |
UNION | 表示此查询是 UNION 的第二或随后的查询 |
DEPENDENT UNION | UNION 中的第二个或后面的查询语句, 取决于外面的查询 |
UNION RESULT | UNION 的结果 |
SUBQUERY | 子查询中的第一个 SELECT |
DEPENDENT SUBQUERY | 子查询中的第一个 SELECT, 取决于外面的查询. 即子查询依赖于外层查询的结果 |
DERIVED | 驱动表 |
MATERIALIZED | 子查询的实现(Materialized subquery) |
UNCACHEABLE SUBQUERY | 不能被缓存的子查询 |
UNCACHEABLE UNION | 在联合查询中的且不能被缓存的子查询中的后续查询 |
查询涉及的表名。算法
查询的记录所在的分区,若是表没有被拆分这个值是Null。sql
链接的类型,不一样的类型及说明以下:缓存
值 | 解释 |
---|---|
system | 这是下面类型const的一种特殊状况。表里只有一条数据。 |
const | 针对主键或者索引的等值查询,该表最多有一个匹配的行,因为只有一行,所以该行中列的值能够被优化器的其他部分视为常量。 |
eq_ref | 当链接使用索引的全部部分而且索引是a PRIMARY KEY或UNIQUE NOT NULL索引时。 |
ref | 全部具备匹配索引值的行都从这个表中读取 |
fulltext | 使用FULLTEXT 索引执行 |
ref_or_null | ref的基础上包含了NULL值的搜索 |
index_merge | 使用索引合并优化 |
unique_subquery | 只是一个索引查找函数,能够彻底替代子查询以提升效率。 |
index_subquery | 取代了IN子查询,但它适用于非惟一索引的子查询。 |
range | 只有在给定范围内的行才能被检索,使用索引来选择行。的key 输出行中的列指示使用哪一个索引。将key_len包含已使用的时间最长的关键部分。该ref列是 NULL用于这种类型的。 |
index | 使用索引查找,如在Extra列看到Using index,说明正在使用覆盖索引,只扫描索引的数据,它比按索引次序全表扫描的开销要小不少 |
ALL | 全表扫描 |
可能被使用的索引,若是此列是NULL,则表示没有相关的索引,能够经过WHERE 子句来检查是否引用某些适合索引或列,从而提升查询的性能。
要查看表有哪些索引,请使用 SHOW INDEX FROM tbl_name
服务器
上面的possible_keys是可能被使用的key,这个式实际被使用的键。
若是 key是NULL,表示MySQL没有发现有索引能够用于更有效地执行查询。要强制MySQL使用索引或忽略索引,可使用FORCE INDEX,USE INDEX
或IGNORE INDEX
语句。函数
被使用索引的长度。取决于key列,若是key为NULL,这列也是NULL。oop
该列显示将哪些列或常量与列中指定的索引进行比较,以 key从表中选择行。性能
MySQL认为查询必须扫描的行数。
对于InnoDB存储引擎,这个数字是估计值,并不老是准确的。
条件过滤后的行占表内总行数的百分比。
表示MySQL解析查询的其余信息。
Extra是EXPLAIN输出中另一个很重要的列,该列显示MySQL在查询过程当中的一些详细信息,MySQL查询优化器执行查询的过程当中对查询计划的重要补充信息。
值 | 解释 |
---|---|
Using filesort | MySQL有两种方式能够生成有序的结果,经过排序操做或者使用索引,当Extra中出现了Using filesort 说明MySQL使用了后者,但注意虽然叫filesort但并非说明就是用了文件来进行排序,只要可能排序都是在内存里完成的。大部分状况下利用索引排序更快,因此通常这时也要考虑优化查询了。使用文件完成排序操做,这是多是ordery by,group by语句的结果,这多是一个CPU密集型的过程,能够经过选择合适的索引来改进性能,用索引来为查询结果排序。 |
Using temporary | 用临时表保存中间结果,经常使用于GROUP BY 和 ORDER BY操做中,通常看到它说明查询须要优化了,就算避免不了临时表的使用也要尽可能避免硬盘临时表的使用。 |
Not exists | MYSQL优化了LEFT JOIN,一旦它找到了匹配LEFT JOIN标准的行, 就再也不搜索了。 |
Using index | 说明查询是覆盖了索引的,不须要读取数据文件,从索引树(索引文件)中便可得到信息。若是同时出现using where,代表索引被用来执行索引键值的查找,没有using where,代表索引用来读取数据而非执行查找动做。这是MySQL服务层完成的,但无需再回表查询记录。 |
Using index condition | 这是MySQL 5.6出来的新特性,叫作“索引条件推送”。简单说一点就是MySQL原来在索引上是不能执行如like这样的操做的,可是如今能够了,这样减小了没必要要的IO操做,可是只能用在二级索引上。 |
Using where | 使用了WHERE从句来限制哪些行将与下一张表匹配或者是返回给用户。注意:Extra列出现Using where表示MySQL服务器将存储引擎返回服务层之后再应用WHERE条件过滤。 |
Using join buffer | 使用了链接缓存:Block Nested Loop,链接算法是块嵌套循环链接;Batched Key Access,链接算法是批量索引链接 |
impossible where | where子句的值老是false,不能用来获取任何元组 |
select tables optimized away | 在没有GROUP BY子句的状况下,基于索引优化MIN/MAX操做,或者对于MyISAM存储引擎优化COUNT(*)操做,没必要等到执行阶段再进行计算,查询执行计划生成的阶段即完成优化。 |
distinct | 优化distinct操做,在找到第一匹配的元组后即中止找一样值的动做。 |
参考
http://www.searchdoc.cn/rdbms/mysql/dev.mysql.com/doc/refman/5.7/en/explain-output.com.coder114.cn.html#explain-extra-information
https://www.jianshu.com/p/ea3fc71fdc45
http://www.deituicms.com/mysql8cn/cn/web.html