携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第6天,点击查看活动详情
通过《四步趟过MySQL之第四步:MySQL优化学习(上)》结尾处学习到如何通过MySQL里的慢查询日志 slow query log和自带的分析工具mysqldumpslow来监控到数据库运行期间查询速度慢的sql,本章会通过使用EXPLAIN 执行计划来分析什么原因导致的sql慢。
EXPLAIN 执行计划
使用方法很简单,在要执行的SQL前加上EXPLAIN即可
这边参考MySQL官方文档来学习
加上EXPLAIN后显示的所有列的作用,其中应该重点关注type、possible_keys、key、Extra
1、id 序号
id是查询序列编号,每张表都是单独访问的,就算是一个联合查询或者各种子查询嵌套的一条SQL,对于MySQL来说,都是需要一张表一张表来查询的,一个SELECT就会有一个序号。
id值不同的时候,先查询id值大的(先大后小):比如子查询,一定是子查询的id大,外层查询的id小;
id值相同时,表的查询顺序是从上往下顺序执行:这种情况一般出现于from后边跟了多张表的情况。
2、select type 查询类型
上图为该列可能会出现的所有类型,我感觉对优化来讲意义不大,实在需要可以去官网查相关属性的含义
3、type 连接类型
所有连接类型中,性能排序:
system > const > eq_ref> ref > fulltext > ref_or_null > index_merger > unique_ subquery > index_subquery > range > index > all
以上所有类型除了all,都能用到索引,以上三种system, const, eq_ ref,都是可遇而不可求的,基本上很难优化到这个状态。
一般来说, 需要保证查询的type至少达到range级别,最好能达到ref。ALL (全表扫描)和index (查询全部索引)都是需要优化的。
在实际场景遇到时,如果时all,就根据业务场景在相应的列加上合适的场景,如果时index,就需要给sql和索引列相关部分加上筛选,就好像java中的设计模式,都各有优劣,不能在项目中强行上所有设计模式,这边也是,不能强行追求所有SQL性能都到system、const级。
4、possible_key、key
可能用到的索引和实际用到的索引。 如果key是NULL就代表没有用到索引。 possible_ key可以有一个或者多个,可能用到索引不代表一定用到索引。
另外:如果触发了覆盖索引的情况下,possible_ key 为空, key(在优化器的优化下,也会使用索引)也会有值。
5、Extra
执行计划给出的额外的信息说明。
| 参数名 | 说明 |
|---|---|
| using index | 用到了覆盖索引,不需要回表。 |
| using where | 使用了where过滤,表示存储引擎返回的记录并不是所有的都满足查询条件,需要在server层进行过滤(跟是否使用索引没有关系)。 |
| Using index condition | 索引条件下推 |
| using filesort | 不能使用索引来排序,用到了额外的排序(跟磁盘或文件没有关系)(常见于order by 后边跟的列不是索引)。需要优化。 |
| using temporary | 用到了临时表。例如:distinct非索引列、group by非索引列等等。需要优化,例如创建复合索引。 |