慢查询指的是数据库中执行时间超过指定阈值的 SQL 语句。不同业务场景下,这个阈值通常各不相同。在我们公司内部,这个阈值被设定为 1 秒钟。也就是说,任何执行时间超过 1 秒的 SQL 语句都会被视为慢查询。
对慢查询进行问题排查通常分为以下几个步骤:
一般而言,慢查询问题相对容易发现。如果有完善的监控体系,系统会定期统计慢 SQL 并通过报警方式提醒。
此外,如果使用了某些数据库中间件,例如 TDDL,它们通常会记录慢 SQL 的日志:
Cause: ERR-CODE: [TDDL-4202][ERR_SQL_QUERY_TIMEOUT] Slow query leads to a timeout exception, please contact DBA to check slow sql. SocketTimout:12000 ms,
如果只依赖 MySQL 本身的话
my.cnf
(或者在 Windows 系统下可能是 my.ini
),通常它们位于 MySQL 安装目录下的 etc
或 conf
文件夹中。
slow_query_log = 1
slow_query_log_file = /path/to/slow-query.log
long_query_time = 1
sudo vi /var/log/mysql/mysql-slow.log
请将路径 /var/log/mysql/mysql-slow.log
替换为实际配置文件中指定的慢查询日志路径。配置完毕后,MySQL 会将执行时间超过 long_query_time
设置的时间阈值的 SQL 语句记录到慢查询日志中。
如果有慢 SQL,内容如下:
# Time: 2023-06-04T12:00:00.123456Z
# User@Host: hollis[192.168.0.1]:3306
# Query_time: 2.345678 Lock_time: 0.012345 Rows_sent: 10 Rows_examined: 100
SET timestamp=1650000000;
SELECT * FROM orders WHERE status = 'pending' ORDER BY gmt_created DESC;
在上述各种监控、报警和日志中,我们可以定位到具体的慢 SQL 语句,然后可以进一步分析为什么这个 SQL 语句执行缓慢,主要是排查以下几个可能的原因:
针对这些问题,可以通过优化数据库表结构、添加合适的索引、优化 SQL 语句写法、调整数据库配置参数等方式来改进 SQL 查询的性能。
具体可参考文章:提升 SQL 查询效率的终极指南
对于大多数情况下的慢 SQL 问题,通常可以通过执行计划分析找出根本原因,主要集中在索引和 JOIN 操作上。关于执行计划分析和索引失效的详细内容,可以参考以下几篇文章,它们介绍得非常详细:
定位问题后,解决问题就会变得容易起来。
实际上,最大的挑战不在于解决问题,而在于准确定位问题。因为一旦问题被准确定位,解决起来就变得相对简单。例如,缺少索引就添加索引,JOIN 操作过多就进行拆分。这里不再详细展开。
好了,本章节到此告一段落。希望对你有所帮助,祝学习顺利。