MySQL慢查询
MySQL慢查询
# 一、MySQL慢查询介绍
在MySQL中执行查询、插入、更新、删除等SQL语句时,如果语句的执行时间超过了设定的时间阈值,改 SQL就会被定义为慢查询SQ。在 MySQL 中这个阈值是由参数 long_query_time
来设置的。当执行的查询语句所需的时间超过了long_query_time
的设定值,MySQL会将这个SQL语句记录在慢查询日志中,以便后续分析。在慢查询日志中,记录了每条慢查询语句的执行耗时、执行的时间点、执行语句的详细信息等内容,可以用于分析SQL查询性能问题,从而进行查询优化。慢查询的原因可能有很多,比如未设置索引,查询条件不当导致索引失效、表结构设计不合理等等。
# 二、MySQL慢查询
# 2.1 查询MySQL慢查询开启状态
# 查看慢查询开启状态和慢查询日志保存路径
在 MySQL 数据库中执行以下命令
show global variables like '%slow_query_log%';
结果如下:
mysql> show global variables like '%slow_query_log%';
+---------------------+------------------------------------------+
| Variable_name | Value |
+---------------------+------------------------------------------+
| slow_query_log | ON |
| slow_query_log_file | /data/apps_data/mysql-data/mysqlslow.log |
+---------------------+------------------------------------------+
2 rows in set (0.00 sec)
2
3
4
5
6
7
8
slow_query_log
:字段值为ON
,则表示已经成功开启了慢查询日志功能,OFF
表示未开启慢查询记录。
slow_query_log_file
:字段值表示慢查询日志的保存路径。
# 查看当前慢查询时间阈值
在 MySQL 数据库中执行以下命令
show variables like '%long_query_time%';
结果如下:
mysql> show variables like '%long_query_time%';
+-----------------+----------+
| Variable_name | Value |
+-----------------+----------+
| long_query_time | 2.000000 |
+-----------------+----------+
1 row in set (0.00 sec)
2
3
4
5
6
7
显示的value
值,即为当前设置的慢查询的时间阈值,单位为秒,如上结果所示,如开启慢查询后,则执行时间超过2秒的SQL将记录在慢查询日志中。
# 2.2 修改MySQL慢查询开启状态
# 2.2.1 MySQL 配置文件修改慢查询
编辑MySQL配置文件my.cnf(或my.ini),保存后重启 MySQL 服务。
# 开启慢查询日志功能
slow_query_log=1
# 慢查询日志文件路径
slow_query_log_file=/var/log/mysql/slow-query.log
# 定义慢查询的时间阈值,单位为秒
long_query_time=10
2
3
4
5
6
# 2.2.2 MySQL 语句修改慢查询
注意:语句方式修改的在 MySQL重启后会失效。
# 开启慢查询日志
set global slow_query_log=on;
# 设置慢查询日志文件保存路径
set global slow_query_log_file='/var/log/mysql/slow-query.log';
# 设置慢查询时间阈值 单位秒,不加global只对当前会话有效
set global long_query_time=2;
# 开启未使用索引SQL记录
set global log_queries_not_using_indexes=on;
2
3
4
5
6
7
8
# 2.3 MySQL慢查询日志
# 2.3.1 MySQL 慢查询日志解析
以下为一条MySQL慢查询日志
的示例
# Time: 2022-01-01T12:34:56.789123Z
# User@Host: dbuser[192.168.0.1] @ mydb
# Query_time: 2.345678 Lock_time: 0.123456 Rows_sent: 10 Rows_examined: 200
SET timestamp=1641032096;
SELECT * FROM mytable WHERE col1 = 'value1' AND col2 = 'value2' ORDER BY col3 DESC LIMIT 10;
2
3
4
5
慢查询日志解析:
第一行 Time(时间戳):SQL执行的时间,上述为 2022年1月1日12时34分56.789123秒,以UTC时间表示。
第二行 User@Host(用户和主机):使用的 MySQL用户名为dbuser,登录的IP地址为192.168.0.1,连接到的数据库为mydb。
第三行 Query_time(查询时间):查询时间为2.345678秒,
Lock_time(锁定时间):锁定时间为0.123456秒,
Rows_sent(返回行数):查询返回了10行数据,
Rows_examined(扫描行数):查询扫描了200行数据。
第四行 SET timestamp(时间戳参数):该查询使用的时间戳参数为1641032096。
第五行 执行的查询SQL语句。
2
3
4
5
6
7
8
9
10
11
12
# 2.3.2 使用mysqldumpslow分析慢查询日志
mysqldumpslow
是MySQL提供的一个命令行工具,用于分析并汇总MySQL慢查询日志文件。它可以帮助我们找出MySQL慢查询的瓶颈,并快速定位优化的方向。
获取mysqldumpslow
可用参数,执行命令mysqldumpslow --help
[root@evan ~]# 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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
特别注意的是-s
参数,表示按指定方式排序。默认按照平均查询时间(at)排序,还可选择,
c: 访问次数
l: 锁定时间
r: 返回记录的行数
t: 查询时间
al:平均锁定时间
ar:平均返回记录的行数
at:平均查询时间
常用分析语句
# 取出查询耗时最久的3条慢查询
# 取出查询耗时最久的3条慢查询
mysqldumpslow -s t -t 3 /data/apps_data/mysql-data/mysqlslow.log
2
# 取出查询耗时最久的且含有transaction的3条慢查询
# 取出查询耗时最久的且含有transaction的3条慢查询
mysqldumpslow -s t -t 3 -g "transaction" /data/apps_data/mysql-data/mysqlslow.log
2
# 取出返回记录行数最多的3条慢查询记录
# 取出返回记录行数最多的3条慢查询记录
mysqldumpslow -s r -t 3 /data/apps_data/mysql-data/mysqlslow.log
2
# 取出访问次数最多的3条慢查询记录
# 取出访问次数最多的3条慢查询记录
mysqldumpslow -s c -t 3 /data/apps_data/mysql-data/mysqlslow.log
2