记录慢查询
- 开启慢查询的配置
- 查看慢查询状态
- 动态开启慢查询日志
- 永久开启配置
- log_throttle_queries_not_using_indexes
- 记录慢查询对性能的影响
- 实际案例说明
- 第一条记录
- 第二条记录
- 第三条记录
- 第四条记录
开启慢查询的配置
查看慢查询状态
- 执行 `show variables like 'slow_query_log%';`,
- 查看 `slow_query_log` 是否为 `ON`,若为 `OFF` 则未开启
- 查看慢查询日志文件路径
动态开启慢查询日志
- 执行
set global slow_query_log='ON';
可动态开启慢查询日志,但数据库重启后会失效
永久开启配置
-
修改
my.cnf
或my.ini
,在[mysqld]
部分添加参数 说明 slow_query_log on :开启 slow_query_log_file 记录慢sql日志路径 long_query_time 默认为 10 秒,查询耗时超过该阈值的 SQL 语句会被记录 log_queries_not_using_indexes on : 查询sql没有使用索引,会记录到慢查询日志中 log_throttle_queries_not_using_indexes = 5 每分钟最多记录 5 次未使用索引的查询 log_slow_slave_statements min_examined_row_limit 扫描行数超过 100 行的查询才会被记录为慢查询 ```sqlslow_query_log = on slow_query_log_file = /u01/soft/oracle/logs/mysqld_slow.log long_query_time = 2log_queries_not_using_indexes = onlog_throttle_queries_not_using_indexes = 5log_slow_slave_statements = 1min_examined_row_limit = 100```
- 保存后重启 MySQL 服务使配置生效
log_throttle_queries_not_using_indexes
- 不是只记录 5 次,而是每分钟最多记录 5 次未使用索引的查询。
-
设置目的
- 这个参数主要是为了防止慢查询日志文件被大量未使用索引的查询信息瞬间淹没。因为在实际的应用场景中,可能会有一些频繁执行但未使用索引的查询语句,如果不加以限制,这些语句的日志记录会迅速占据大量的存储空间,使得日志文件变得臃肿,不方便对真正有价值的慢查询信息进行分析。
-
工作原理
- 当开启
log_queries_not_using_indexes
选项后,MySQL 会检查查询语句是否使用了索引。如果没有使用索引,并且符合其他慢查询的条件(如查询时间超过long_query_time
设定的阈值等),MySQL 会准备记录这条查询语句到慢查询日志中。 - 但是,为了控制记录的频率,
log_throttle_queries_not_using_indexes
就发挥作用了。例如,当设置为 5 时,每分钟最多记录 5 次未使用索引的查询。如果在这一分钟内有大量未使用索引的查询,超过 5 次后,后续的同类查询在这一分钟内就不会再被记录了。这样既能保证能够获取到未使用索引查询的关键信息,又能够避免日志文件被过多相似的记录填满。
- 当开启
记录慢查询对性能的影响
开启慢查询日志会对系统性能产生一定影响,因为记录日志需要消耗磁盘 I/O 资源。在高并发写入的场景下,这种影响可能会稍明显。如果 MySQL 是主从结构,可考虑在从服务器上开启慢查询日志,以减少对主服务器性能的影响
实际案例说明
# User@Host: root[root] @ serverName [10.256.22.2] Id: 249625
# Query_time: 0.016972 Lock_time: 0.000005 Rows_sent: 11 Rows_examined: 19185
use test-dev;
SET timestamp=1749630891;
SELECT * FROM *** GROUP BY **;
# Time: 2025-06-11T16:35:44.791481+08:00
# User@Host: [] @ [] Id: 249254
# Query_time: 0.041186 Lock_time: 0.000076 Rows_sent: 0 Rows_examined: 0
use tmp_dev;
SET timestamp=1749630944;
throttle: 17 'index not used' warning(s) suppressed.;
# Time: 2025-06-11T16:36:44.807640+08:00
# User@Host: [] @ [] Id: 249254
# Query_time: 0.015413 Lock_time: 0.000041 Rows_sent: 0 Rows_examined: 0
SET timestamp=1749631004;
throttle: 11 'index not used' warning(s) suppressed.;
# Time: 2025-06-11T16:37:44.821526+08:00
# User@Host: [] @ [] Id: 249565
# Query_time: 0.010364 Lock_time: 0.000032 Rows_sent: 0 Rows_examined: 0
SET timestamp=1749631064;
throttle: 13 'index not used' warning(s) suppressed.;
在 MySQL 慢查询日志中,每条记录通常以 # User@Host:
开始,接着记录了查询的执行时间、用户、主机、查询相关的性能指标,以及查询语句本身等信息。以下是对上述日志信息的详细解释:
第一条记录
-
# User@Host: root[root] @ serverName [10.256.22.2] Id: 249625
- 表示执行查询的用户是
root
,客户端主机是serverName
,其 IP 地址是10.256.22.2
,连接的线程 ID 是 249625。
- 表示执行查询的用户是
-
# Query_time: 0.016972 Lock_time: 0.000005 Rows_sent: 11 Rows_examined: 19185
Query_time
:查询实际执行的时间是 0.016972 秒。Lock_time
:获取锁所花费的时间是 0.000005 秒。Rows_sent
:查询返回的行数是 11 行。Rows_examined
:查询过程中扫描的行数是 19185 行,这表明查询可能没有使用索引或者索引使用效率低,导致扫描了大量的数据行。
-
use test-dev;
- 表示该查询是在
test-dev
数据库中执行的。
- 表示该查询是在
-
SET timestamp=1749630891;
- 设置了时间戳,对应的时间可以通过 Unix 时间戳转换工具转换为具体时间。
-
SELECT ...
- 这是具体的查询语句。
-
# Time: 2025-06-11T16:35:44.791481+08:00
- 这是查询执行的时间戳,表明该查询是在 2025 年 6 月 11 日 16 点 35 分 44 秒左右执行的。
第二条记录
-
# User@Host: [] @ [] Id: 249254
- 这里的用户和主机信息显示为
[]
,可能是因为在日志中未记录具体的用户和主机信息,或者该查询是由系统内部进程或其他未明确标识的客户端发起的,连接的线程 ID 是 249254。
- 这里的用户和主机信息显示为
-
# Query_time: 0.041186 Lock_time: 0.000076 Rows_sent: 0 Rows_examined: 0
Query_time
:查询实际执行的时间是 0.041186 秒。Lock_time
:获取锁所花费的时间是 0.000076 秒。Rows_sent
:查询返回了 0 行数据。Rows_examined
:查询过程中没有扫描到任何行,这可能是因为查询条件没有匹配到任何数据,或者表中没有数据。
-
use tmp_dev;
- 表示该查询是在
tmp_dev
数据库中执行的。
- 表示该查询是在
-
SET timestamp=1749630944;
- 设置了时间戳,对应的时间可以通过 Unix 时间戳转换工具转换为具体时间。
-
throttle: 17 'index not used' warning(s) suppressed.;
- 这提示有 17 个 “index not used” 的警告被抑制,表明该查询没有使用索引,这可能是导致查询性能不佳的一个因素。
-
# Time: 2025-06-11T16:36:44.807640+08:00
- 这是查询执行的时间戳,表明该查询是在 2025 年 6 月 11 日 16 点 36 分 44 秒左右执行的。
第三条记录
-
# User@Host: [] @ [] Id: 249254
- 同样未明确显示用户和主机信息,连接的线程 ID 是 249254。
-
# Query_time: 0.015413 Lock_time: 0.000041 Rows_sent: 0 Rows_examined: 0
Query_time
:查询实际执行的时间是 0.015413 秒。Lock_time
:获取锁所花费的时间是 0.000041 秒。Rows_sent
:查询返回了 0 行数据。Rows_examined
:查询过程中没有扫描到任何行。
-
SET timestamp=1749631004;
- 设置了时间戳,对应的时间可以通过 Unix 时间戳转换工具转换为具体时间。
-
throttle: 11 'index not used' warning(s) suppressed.;
- 提示有 11 个 “index not used” 的警告被抑制,表明该查询也没有使用索引。
-
# Time: 2025-06-11T16:37:44.821526+08:00
- 这是查询执行的时间戳,表明该查询是在 2025 年 6 月 11 日 16 点 37 分 44 秒左右执行的。
第四条记录
-
# User@Host: [] @ [] Id: 249565
- 未明确显示用户和主机信息,连接的线程 ID 是 249565。
-
# Query_time: 0.010364 Lock_time: 0.000032 Rows_sent: 0 Rows_examined: 0
Query_time
:查询实际执行的时间是 0.010364 秒。Lock_time
:获取锁所花费的时间是 0.000032 秒。Rows_sent
:查询返回了 0 行数据。Rows_examined
:查询过程中没有扫描到任何行。
-
SET timestamp=1749631064;
- 设置了时间戳,对应的时间可以通过 Unix 时间戳转换工具转换为具体时间。
-
throttle: 13 'index not used' warning(s) suppressed.;
- 提示有 13 个 “index not used” 的警告被抑制,表明该查询也没有使用索引。
-
# Time: 2025-06-11T16:38:44.83+08:00
- 这是查询执行的时间戳,表明该查询是在 2025 年 6 月 11 日 16 点 38 分 44 秒左右执行的。
综上所述,在这些慢查询日志记录中,有的查询返回了数据并扫描了大量行,有的查询未返回数据且没有扫描到行,且很多查询存在未使用索引的情况,这可能是导致查询速度慢或效率低的原因之一。