mysql慢查询日志是记录执行时间超过指定阈值的SQL语句的日志文件,通过分析这些日志可以快速定位数据库中执行效率低下的SQL,进而针对性优化提升整体性能。开启慢查询日志是分析的前提,默认情况下mysql可能不会开启该功能,需要手动配置相关参数。

开启mysql慢查询日志
首先需要确认慢查询日志是否已经开启,可以执行以下SQL语句查看当前配置:
-- 查看慢查询日志是否开启 SHOW VARIABLES LIKE 'slow_query_log'; -- 查看慢查询的时间阈值,单位秒 SHOW VARIABLES LIKE 'long_query_time'; -- 查看慢查询日志的存储路径 SHOW VARIABLES LIKE 'slow_query_log_file';
如果需要开启慢查询日志,可以执行如下配置语句,也可以将这些配置写入mysql的配置文件中永久生效:
-- 开启慢查询日志 SET GLOBAL slow_query_log = 'ON'; -- 设置慢查询时间阈值为2秒,执行时间超过2秒的SQL会被记录 SET GLOBAL long_query_time = 2; -- 设置慢查询日志存储路径,路径需要mysql有写入权限 SET GLOBAL slow_query_log_file = '/var/lib/mysql/slow.log';
直接查看慢查询日志文件
慢查询日志本质是一个文本文件,可以直接使用Linux的cat、less、tail等命令查看内容,日志中每条记录会包含SQL执行时间、锁等待时间、返回行数、执行的具体SQL等信息。以下是一个典型的慢查询日志记录示例:
# Time: 2024-05-20T10:30:00.123456Z # User@Host: root[root] @ localhost [] Id: 123 # Query_time: 3.234567 Lock_time: 0.001234 Rows_sent: 10 Rows_examined: 100000 SET timestamp=1716196200; SELECT * FROM user_table WHERE name LIKE '%测试%';
其中Query_time是SQL总执行时间,Lock_time是等待锁的时间,Rows_examined是扫描的行数,Rows_sent是返回给客户端的行数。如果扫描行数远大于返回行数,通常说明SQL没有合理走索引。
使用mysqldumpslow工具分析
mysql自带了mysqldumpslow工具,可以对慢查询日志进行汇总统计,避免手动查看大量重复日志,常用参数如下:
-s:排序方式,可选t(按查询时间排序)、c(按出现次数排序)、l(按锁时间排序)、r(按返回行数排序)-t:指定输出前多少条记录-a:不将数字替换为N,字符串替换为S-g:过滤包含指定字符串的SQL
以下是几个常用的命令示例:
-- 按查询时间排序,输出前10条慢查询 mysqldumpslow -s t -t 10 /var/lib/mysql/slow.log -- 过滤包含user_table的慢查询,输出前5条 mysqldumpslow -s t -t 5 -g "user_table" /var/lib/mysql/slow.log -- 不替换变量,按出现次数排序输出前10条 mysqldumpslow -s c -t 10 -a /var/lib/mysql/slow.log
结合explain分析慢查询SQL
找到慢查询的具体SQL后,需要使用EXPLAIN命令分析SQL的执行计划,判断索引使用情况、扫描范围等问题。以下是使用explain分析的示例:
-- 对慢查询SQL添加EXPLAIN前缀查看执行计划 EXPLAIN SELECT * FROM user_table WHERE name LIKE '%测试%';
执行后会返回如下关键字段:
| 字段名 | 含义说明 |
|---|---|
| id | 查询的序列号,表示查询的执行顺序 |
| select_type | 查询类型,比如SIMPLE(简单查询)、PRIMARY(主查询)、SUBQUERY(子查询)等 |
| table | 当前查询涉及的表 |
| type | 访问类型,性能从好到坏为system>const>eq_ref>ref>range>index>ALL,出现ALL表示全表扫描 |
| possible_keys | 可能使用的索引 |
| key | 实际使用的索引,为NULL表示未使用索引 |
| rows | 预估扫描的行数,数值越大性能越差 |
| Extra | 额外信息,比如Using filesort(需要额外排序)、Using temporary(使用临时表)都表示性能问题 |
慢查询优化实践
根据慢查询日志和分析结果,常见的优化方向如下:
- 为查询条件的字段添加合适的索引,避免全表扫描,注意
LIKE '%关键字%'无法使用普通索引,可考虑全文索引 - 优化SQL写法,避免
SELECT *,只查询需要的字段,减少数据传输和扫描开销 - 减少子查询的使用,尽量使用关联查询替代,避免多层嵌套查询
- 对于大表查询,可考虑分库分表或者读写分离,降低单表压力
- 定期清理无用的索引,避免索引过多影响写入性能
如果是频繁执行的慢查询,优化后可以通过再次查看慢查询日志确认问题是否解决,同时可以调整long_query_time的阈值,逐步优化更短耗时的SQL,提升数据库整体响应速度。