目录
- 1-引言:什么是慢查询
- 1-1 慢查询定义
- 1-2 为什么排查慢查询
- 2-核心:慢查询排查
- 2-1 慢查询定位
- 2-2 慢查询解决
- 2-2-1 Explain 排查慢查询
- 2-2-2 Explain 重点关键字
- 3-总结:慢查询知识点小结
1-引言:什么是慢查询
1-1 慢查询定义
- 定义:在MySQL中,慢查询是指执行时间超过预设阈值的SQL语句。这种查询的执行时间长,效率低下,通常需要优化。
- 阈值:慢查询日志通过
long_query_time
变量定义超时时间。任何查询执行时间超过这个值的,都会被记录到慢查询日志中。 - 根据业务场景的不同,这个阈值的设定是不一样的,如果业务内部设置慢查询的阈值为 1s,则一条 SQL 语句在执行的过程中超过了 1 秒,则会被记录为慢查询。
1-2 为什么排查慢查询
提升应用性能
- 慢查询是影响应用程序性能的主要瓶颈之一。查询执行时间长会直接导致用户体验差,特别是在数据驱动的应用中,响应时间是用户满意度的关键因素。通过优化慢查询,可以显著减少请求的响应时间,提高整体应用性能。
避免潜在的锁竞争和死锁
- 慢查询可能会持有长时间的锁,增加死锁的风险,尤其是在涉及多个表或多行的复杂查询中。这种锁竞争会影响数据库的并发处理能力,造成更多的性能问题。优化慢查询有助于减少锁的持有时间,提高并发性能。
2-核心:慢查询排查
2-1 慢查询定位
慢查询定位方式可以通过 配置MySQL自带的慢查询日志、
- 根据 位于 MySQL 安装目录下 etc 或 conf 中的 MySQL 的配置文件 my.ini (或 my.cnf)
- 在配置文件中启用慢查询日志:找到或添加配置项,并取消注释
# 启用慢查询日志,记录执行时间超过长查询时间的查询。
slow_query_log = 1
# 指定存储慢查询日志的文件路径。
slow_query_log_file = /path/to/slow-query.log
# 设置被认为是慢查询的阈值(单位:秒)。
long_query_time = 1
- 重启MySQL服务:保存配置文件并重启MySQL服务,以使得配置文件生效
sudo systemctl restart mysql
- 查看慢查询日志内容:根据上述配置文件的路径,查看慢查询日志(Linux)
vim /path/to/slow-query.log
慢查询日志示例:
# Time: 2024-04-18T08:22:34.983941Z
# User@Host: root[root] @ localhost [127.0.0.1]
# Query_time: 11.293402 Lock_time: 0.000137 Rows_sent: 45 Rows_examined: 89723
SET timestamp=1650277354;
SELECT * FROM orders WHERE date BETWEEN '2024-04-01' AND '2024-04-18';
- Time:
- 日志记录的时间戳,指示查询执行的具体时间。
- User@Host:
- 执行查询的数据库用户及其来源主机。
- Query_time: 查询执行的总时间,单位是秒;
- Lock_time:查询在等待锁的时间,单位是秒;
- **Rows_sent:**查询结果发送给客户端的行数。;
- Rows_examined:查询过程中检查的行数,反映了查询的负载。
- SET timestamp:设置查询发生时间的时间戳,有助于复现查询环境。
- SQL Query:
- 实际执行的SQL查询语句。
2-2 慢查询解决
慢查询的常见原因:
- 索引缺失或不适当:如果查询中涉及的表缺少适当的索引,数据库需要进行全表扫描来查找数据,这通常是导致查询变慢的主要原因之一。
- SQL语句问题:复杂的查询、过度使用子查询、错误的连接(例如笛卡尔连接)或未能有效使用MySQL的优化器都可能导致性能问题。
2-2-1 Explain 排查慢查询
Explain 语句的作用
在MySQL中,EXPLAIN语句是一种非常有用的工具,用于帮助开发者和数据库管理员理解MySQL是如何执行一个特定的查询语句的。通过使用EXPLAIN,你可以获得关于SQL执行计划的详细信息,这包括查询如何使用索引,以及在查询过程中涉及哪些表和操作。这些信息对于优化查询性能至关重要。
- 通过explain关键字可以查看sql语句的执行计划来评估sql语句的性能!
2-2-2 Explain 重点关键字
主要关注** type、key、rows、Extra **这四个字段
**① ✨type关键字 **表示访问方法,性能由好到差:NULL
、system
、const
、eq_ref
、ref
、range
、index
、all
- 越往前越好,一般业务中不会出现优化到NULL的情况
- 根据主键/唯一索引进行访问,一般会出现const
- 根据非唯一性的索引进行访问时,一般会出现ref
- index:表示使用了索引,但是要对整个索引树进行扫描…虽然比 all 好一点,但性能也不是特别好!
- all:全表扫描…
② ✨Key关键字:实际用到的索引,如果为 NULL 则表示没有使用索引
③ ✨rows 关键字:MySQL认为必须要执行查询的行数,在 InnoDB引擎的表中,是一个估计值,可能并不总是准确的。
④ ✨Extra 关键字:Extra列提供了关于MySQL如何执行查询的额外信息。这些信息对于理解查询执行的具体细节以及优化查询性能非常有用。Extra列中的信息可以帮助你识别查询中的潜在性能问题,例如是否进行了文件排序、是否使用了临时表、是否利用了索引等。
- Extra 关键字中各个结果含义
- 1、
using index
:满足了覆盖索引,不需要回表.直接返回给server层 - 2、
using index condition
- 使用了索引下推…搜索的列存在于索引列,但是无法为其生产扫描区间…
- 有些搜索条件虽然包含了索引列,但是无法为其生成扫描区间.(索引下推优化…也会有回表,只是减少回表次数…)
- 3、
using where
- 有搜索条件必须要在server进行判断(过滤),而不能直接在存储引擎层基于索引就完成所有判断.
- 在server还要完成对别的条件的过滤!
- 4、
using filesort
- 无法在索引下直接完成排序,而是需要开辟新的内存空间来进行排序!
- 5、
using join buffer
- 联表查询时,采用了基于块的循环嵌套连接算法来优化.开辟一个join buffer来存放驱动表中查询出来
- 符合条件的记录,减少对被驱动表的访问次数.没有加索引…
- 6、
using temporary
- 使用了临时表,性能并不好!
3-总结:慢查询知识点小结
MySQL慢查询怎么办?需要关注Explain的哪些关键字?