EXPLAIN关键字
前言
距离上次更新过去了差不多一个月,主要一直在忙八股和项目,然后就是投简历改简历,我觉得这是一个瓶颈期,因为一直没有正反馈,也许许多人就栽在这段时期吧,迷茫、焦虑,尤其是面对这样的环境,我希望好好沉下心,打好基础,没有机会就先沉淀,不知道过些日子,再回头看看自己写下的这段话,会有什么感想。
欲渡黄河冰塞川,将登太行雪满山:李白在《行路难·其一》中用此句,以渡河被冰堵塞、登山被雪阻挡,象征人生道路上仕途受阻,充满艰难险阻。
EXPLAIN
Q:我们为什么要使用explain?
A:帮助我们分析sql语句的执行过程
我们想要知道一条sql语句的执行时间可以这样操作:
1 | -- 1. 首先检查 profiling 功能是否开启,默认可能是关闭的 |
这样太慢了,我们只需要分析那些“慢SQL”,那些影响我们程序执行的SQL,我们可以通过开启慢日志帮助分析
1 | -- 1. 开启慢日志功能 |
好了,现在我们知道有哪些SQL会拖慢程序,我们想要优化它,那我们如何判断优化点在哪里呢?
这就要引入我们的explain关键字,他有一些参数可以帮助我们分析SQL语句的性能
explain各个字段代表的意思
- id :select查询的序列号,包含一组数字,表示查询中执行select子句或操作表的顺序
- select_type :查询类型 或者是 其他操作类型
- table :正在访问哪个表
- partitions :匹配的分区
- type :访问的类型
- possible_keys :显示可能应用在这张表中的索引,一个或多个,但不一定实际使用到
- key :实际使用到的索引,如果为NULL,则没有使用索引
- key_len :表示索引中使用的字节数,可通过该列计算查询中使用的索引的长度
- ref :显示索引的哪一列被使用了,如果可能的话,是一个常数,哪些列或常量被用于查找索引列上的值
- rows :根据表统计信息及索引选用情况,大致估算出找到所需的记录所需读取的行数
- filtered :查询的表行占表的百分比
- Extra :包含不适合在其它列中显示但十分重要的额外信息
这么多,咱们也记不住呀,其实我们只需要关注那些特别影响性能的字段
重点字段以及优化
如果希望了解得更详细些可以看这篇文章MySQL explain 应用详解(吐血整理🤩) - 个人文章 - SegmentFault 思否
假设现在表结构是这样的
分析下面这样一条SQL
1 | explain select * from orders |
type是最重要的字段,性能好不好主要就看走什么类型的查询,性能排序如下
- system > const > eq_ref > ref > range > index > ALL
可以看到我们的案例走的是ALL全表扫描,这种类型性能最差,因为每个字段都要匹配一次
possible_keys字段显示我们的SQL并没有使用索引,所以key和key_len都显示为null,一般我们希望key_len的值越小越好
Extra字段会显示一些额外信息用来总结你使用了什么到这条SQL
Extra: 包含不适合在其他列显示的额外信息。常见的重要值:
Using filesort
: 表示MySQL无法利用索引完成排序,需要额外的排序操作。通常出现在ORDER BY
子句中。需要优化。Using temporary
: 使用了临时表来保存中间结果。常见于排序(GROUP BY
,ORDER BY
)和子查询。对性能影响较大,需要优化。Using index
: 好现象! 表示使用了覆盖索引(Covering Index),即所有需要的数据都在索引中,不需要回表查询数据行。Using where
: 表示在存储引擎检索行后进行了过滤。
我想针对该SQL进行优化,如果我针对user_id和amount、order_id建立单列索引(有关索引的知识在我上一期博客),它会变成这样,这样我们就成功将查询类型变成了ref,通常我们希望且能达到的类型也是ref
1 | CREATE INDEX idx_user_id ON orders(user_id); |
或者我们尽可能使用主键进行查询,这样会直接在索引中找到对应信息,不需要回表查询
1 | explain select user_id, amount from orders where id = 4; |
感谢你看到这里!