开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」[的第9天](点击查看活动详情)
问题来源
记得一次面试的时候,面试官问我:了解MySQL中的执行计划吗?里面的那些参数表示什么含义呢?那些参数要重点关注下 这个时候脑壳一紧,还好之前有看过执行计划explain相关的知识点,下面来看看Explain执行计划的使用方法
explain执行计划
- 执行代码如下,没有where条件
EXPLAIN SELECT * from t_im_contacts
执行结果是在这样的
- 有where条件,执行代码如下
EXPLAIN SELECT * from t_im_contacts where userId=100
执行结果是这样的:
3.where条件有多个,执行代码如下
EXPLAIN SELECT * from t_im_contacts where contacts=-1 and userId = 100 ;
执行结果是这样的:Extra出现using index condition
观察分析
最主要观察 key 这一列,key 这一列表示实际使用的索引,如果为 NULL 则表示未使用索引,反之则使用了索引。
以上所有结果列说明如下:
| 参数 | 说明 |
|---|---|
| id | 选择标识符,id 越大优先级越高,越先被执行; |
| select_type | 表示查询的类型 |
| table | 输出结果集的表 |
| partitions | 匹配的分区 |
| type | 表示表的连接类型,类型有很多单独说明下 |
| possible_keys | 表示查询时,可能使用的索引 |
| key | 表示实际使用的索引 |
| key_len | 索引字段的长度 |
| ref | 列与索引的比较 |
| rows | 大概估算的行数 |
| filtered | 按表条件过滤的行百分比 |
| Extra | 执行情况的描述和说明 |
最重要的就是 type 字段,type 值类型如下:
- all — 扫描全表数据;
- index — 遍历索引;
- range — 索引范围查找;
- index_subquery — 在子查询中使用 ref;
- unique_subquery — 在子查询中使用 eq_ref;
- ref_or_null — 对 null 进行索引的优化的 ref;
- fulltext — 使用全文索引;
- ref — 使用非唯一索引查找数据;
- eq_ref — 在 join 查询中使用主键或唯一索引关联;
- const — 将一个主键放置到 where 后面作为条件查询, MySQL 优化器就能把这次查询优化转化为一个常量,如何转化以及何时转化,这个取决于优化器,这个比 eq_ref 效率高一点。
还有Extra说明一下
- 出现 null
表示查询的列未被索引覆盖,且where筛选条件是索引的前导列,这意味着用到了索引,但是部分字段未被索引覆盖,必须通过“回表查询”来实现,性能不是很好。
- Using index condition
表示查询条件中虽然出现了索引列,但是有部分条件无法使用索引,会根据能用索引的条件先搜索一遍再匹配无法使用索引的条件。
- Using index
使用索引,表示索引能够覆盖所有的查询字段,无需进行回表查询所以效率会高。大部分情况代表最优
- Using where 单独出现
表示当前查询的字段不能被索引覆盖,所以可能会产生回表,效率略低
- Using where,Using index
表示查询的列被索引覆盖,且where筛选条件是索引列前导列的一个范围,或者是索引列的非前导列。 效率比较高
- Using filesort
这种情况是在使用 order by 关键字的时候,如果待排序的内容无法通过索引直接直接进行排序,mysql就有可能进行文件排序。但是由于查询次数过多的话,对于排序的效率还是有一定的影响的。可以通过设置 max_length_for_sort_data 来提高 order by 的效率。如果操作的数据大小高于max_length_for_sort_data 的缓存大小时,mysql会产生临时表进行查询,一定程度上会影响效率。 max_length_for_sort_data的默认值1024。
优化方案:
优化业务逻辑,不使用 order by ,而在业务代码中执行排序方法设置索引,将带排序的内容放在索引中,直接利用索引进行排序。
总结
MySQL 索引失效的常见场景有以下 几种:
- 联合索引不满足最左匹配原则,看上图3where条件多个情况下就失效了。
- 模糊查询最前面的为不确定匹配字符。
- 索引列参与了运算。
- 索引列使用了函数。
- 索引列存在类型转换。
- 索引列使用 is not null 查询。
所以掌握了这些,就可以和面试官好好聊一下执行计划的使用了。这也是基础知识点,要记牢。