面试的时候面试官问我:“了解MySQL的执行计划吗?”

109 阅读4分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」[的第9天](点击查看活动详情)

问题来源

记得一次面试的时候,面试官问我:了解MySQL中的执行计划吗?里面的那些参数表示什么含义呢?那些参数要重点关注下 这个时候脑壳一紧,还好之前有看过执行计划explain相关的知识点,下面来看看Explain执行计划的使用方法

explain执行计划

  1. 执行代码如下,没有where条件
EXPLAIN SELECT * from t_im_contacts

执行结果是在这样的 image.png

  1. 有where条件,执行代码如下
EXPLAIN SELECT * from t_im_contacts where userId=100

执行结果是这样的: image.png

3.where条件有多个,执行代码如下

EXPLAIN SELECT * from t_im_contacts  where  contacts=-1 and userId = 100 ;

执行结果是这样的:Extra出现using index condition

image.png

观察分析

最主要观察 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 索引失效的常见场景有以下 几种:

  1. 联合索引不满足最左匹配原则,看上图3where条件多个情况下就失效了。
  2. 模糊查询最前面的为不确定匹配字符。
  3. 索引列参与了运算。
  4. 索引列使用了函数。
  5. 索引列存在类型转换。
  6. 索引列使用 is not null 查询。

所以掌握了这些,就可以和面试官好好聊一下执行计划的使用了。这也是基础知识点,要记牢。