MySQL调优之慢查询日志应用

慢查询日志是用于记录SQL执行时间超过某个临界值的SQL日志文件,可用于快速定位慢查询,为我们的SQL优化做参考。

具体指运行时间超过long_query_time值的SQL,则会被记录到慢查询日志中。long_query_time的默认值为10,意思是运行10秒以上的SQL语句。

查看是否开启

show variables like '%slow_query_log%'

# 本文这里结果如下
slow_query_log ON
slow_query_log_file DESKTOP-KIHKQLG-slow.log

​slow_query_log_file​​​指的是慢查询日志文件。如果slow_query_log 状态值为OFF,可以使用​​set GLOBAL slow_query_log = on​​来开启,如果想永久生效,那么在MySQL的配置文件中进行配置。

[-slow.log
#如果不指定日志文件,那么系统会默认一个hostnam-slow.log

查看时间阈值

默认值是10秒,可以根据需求自行调整。

show variables like 'long_query_time';

# 临时设置为1 秒,重启失效
set GLOBAL long_query_time= 1

查询当前慢查询SQL条数

show global status like '%Slow_queries%'

慢查询日志格式

需要注意的是,慢查询日志文件里面不止有Query哦,只要执行时间大于我们设置的阈值都会进入。

如下所示是一个慢查询实例,其load了21W条数据。

# Time: 2022-09-14T05:43:57.174825Z
# User@Host: root[root] @ localhost [127.0.0.1] Id: 2497
# Query_time: 1.697595 Lock_time: 0.000226 Rows_sent: 210001 Rows_examined: 210001
SET timestamp=1663134237;
/* ApplicationName=DBeaver 7.3.0 - SQLEditor <Script-236.sql> */ select * from tb_sys_user tsu limit 210001;

日志分析工具mysqldumpslow

mysql提供了日志分析工具mysqldumpslow来帮助我们快速定位问题。

[root@VM-24-14-centos ~]# mysqldumpslow --help
Usage: mysqldumpslow [ OPTS... ] [ LOGS... ]

Parse and summarize the MySQL slow query log. Options are

--verbose verbose
--debug debug
--help write this text to standard output

-v verbose
-d debug
-s ORDER what to sort by (al, at, ar, c, l, r, t), 'at' is default
al: average lock time
ar: average rows sent
at: average query time
c: count
l: lock time
r: rows sent
t: query time
-r reverse the sort order (largest last instead of first)
-t NUM just show the top n queries
-a don't abstract all numbers to N and strings to 'S'
-n NUM abstract numbers with at least n digits within names
-g PATTERN grep: only consider stmts that include this string
-h HOSTNAME hostname of db server for *-slow.log filename (can be wildcard),
default is '*', i.e. match all
-i NAME name of server instance (if using mysql.server startup script)
-l don't subtract lock time from total time

得到返回记录集最多的10个SQL

mysqldumpslow -s r -t 10 /var/data/mysql-slow.log

得到访问次数最多的10个SQL

mysqldumpslow -s c -t 10 /var/data/mysql-slow.log

得到按照时间排序的前10条SQL中包含左连接的语句

mysqldumpslow -s t -t 10 -g "left join" /var/data/mysql-slow.log

慢查询日志场景应用

慢查询的优化首先要搞明白慢的原因是什么, 是查询条件没有命中索引?是 load了不需要的数据列?还是数据量太大?所以优化也是针对这三个方向来的。

​首先分析语句,看看是否load了额外的数据​​,可能是查询了多余的行并且抛弃掉了,可能是加载了许多结果中并不需要的列,对语句进行分析以及重写。

​分析语句的执行计划,然后获得其使用索引的情况​​,之后修改语句或者修改索引,使得语句可以尽可能的命中索引。

​如果对语句的优化已经无法进行,可以考虑表中的数据量是否太大​​,如果是的话可以进行横向或者纵向的分表。

全局查询日志

其同样可以帮助我们定位SQL问题,通常不建议在生产环境开启。可以在配置文件my.cnf下进行启用:

# 开启
general_log=1
#记录日志文件的路径
general_log_file=/var/data/mysql_general_log
#输出格式
log_output=FILE

或者临时开启:

set global general_log=1;
set global log_output='TABLE'

此时SQL语句将会记录到MySQL库的​​mysql.general_log​​表中。