面试官:MySQL 如何根据执行计划调优 SQL 语句?

上篇文章讲了 MySQL 架构体系,了解到 MySQL Server 端的优化器可以生成 Explain 执行计划,而执行计划可以帮助我们分析 SQL 语句性能瓶颈,优化 SQL 查询逻辑,今天就一块学习 Explain 执行计划的具体用法。
1. explain 的使用
使用 EXPLAIN 关键字可以模拟优化器执行 SQL 语句,分析你的查询语句或是结构的性能瓶颈。在 select 语句之前增加 explain 关键字,MySQL 会在查询上设置一个标记,执行查询会返回执行计划的信息,并不会执行这条 SQL。就比如下面这个:

输出这么多列都是干嘛用的?
其实大都是 SQL 语句的性能统计指标,先简单总结一下每一列的大致作用,下面详细讲一下:

2. explain 字段详解
下面就详细讲一下每一列的具体作用。
1. id 列
id 表示查询语句的序号,自动分配,顺序递增,值越大,执行优先级越高。

id 相同时,优先级由上而下。

2. select_type 列
select_type 表示查询类型,常见的有 SIMPLE 简单查询、PRIMARY 主查询、SUBQUERY 子查询、UNION 联合查询、UNION RESULT 联合临时表结果等。

3. table 列
table 表示 SQL 语句查询的表名、表别名、临时表名。

4. partitions 列
partitions 表示 SQL 查询匹配到的分区,没有分区的话显示 NULL。

5. type 列
type 表示表连接类型或者数据访问类型,就是表之间通过什么方式建立连接的,或者通过什么方式访问到数据的。
具体有以下值,性能由好到差依次是:
system > const > eq_ref > ref > fulltext > ref_or_null > index_merge > unique_subquery > index_subquery > range > index > ALL
system
当表中只有一行记录,也就是系统表,是 const 类型的特列。

const
表示使用主键或者唯一性索引进行等值查询,最多返回一条记录。性能较好,推荐使用。

eq_ref
表示表连接使用到了主键或者唯一性索引,下面的 SQL 就用到了 user 表主键 id。

ref
表示使用非唯一性索引进行等值查询。

ref_or_null
表示使用非唯一性索引进行等值查询,并且包含了 null 值的行。

index_merge
表示用到索引合并的优化逻辑,即用到的多个索引。

range
表示用到了索引范围查询。

index
表示使用索引进行全表扫描。

ALL
表示全表扫描,性能最差。

6. possible_keys 列
表示可能用到的索引列,实际查询并不一定能用到。

7. key 列
表示实际查询用到索引列。

8. key_len 列
表示索引所占的字节数。

每种类型所占的字节数如下:
9. ref 列
表示 where 语句或者表连接中与索引比较的参数,常见的有 const(常量)、func(函数)、字段名。
如果没用到索引,则显示为 NULL。



10. rows 列
表示执行 SQL 语句所扫描的行数。

11. filtered 列
表示按条件过滤的表行的百分比。

用来估算与其他表连接时扫描的行数,row x filtered = 252004 x 10% = 25 万行
12. Extra 列
表示一些额外的扩展信息,不适合在其他列展示,却又十分重要。
Using where
表示使用了 where 条件搜索,但没有使用索引。

Using index
表示用到了覆盖索引,即在索引上就查到了所需数据,无需二次回表查询,性能较好。

Using filesort
表示使用了外部排序,即排序字段没有用到索引。

Using temporary
表示用到了临时表,下面的示例中就是用到临时表来存储查询结果。

Using join buffer
表示在进行表关联的时候,没有用到索引,使用了连接缓存区存储临时结果。
下面的示例中 user_id 在两张表中都没有建索引。

Using index condition
表示用到索引下推的优化特性。

相关视频解析:根据执行计划调优SQL语句
知识点总结:
本文详细介绍了 Explain 使用方式,以及每种参数所代表的含义。无论是工作还是面试,使用 Explain 优化 SQL 查询,都是必备的技能,一定要牢记。
下篇再一块学习一下 SQL 查询的其他优化方式,敬请期待。

原文链接:https://www.cnblogs.com/yidengjiagou/p/16527697.html
评论