2. MySQL 慢查询日志基础:如何开启与核心参数详解
慢查询日志是 MySQL 数据库性能诊断的第一道防线。它记录了执行时间超过指定阈值或未使用索引的 SQL 语句,是定位慢 SQL、优化索引和调整连接池参数的重要依据。本章将详细介绍如何开启慢查询日志,并深入解析 long_query_time 与 log_queries_not_using_indexes 两个核心参数。
2.1 开启慢查询日志
慢查询日志默认是关闭的,需要通过修改 MySQL 配置文件或使用 SET 命令动态开启。推荐在生产环境中同时使用文件记录和系统表 mysql.slow_log 两种方式,以便于分析和监控。
2.1.1 动态开启(无需重启)
-- 开启慢查询日志
SET GLOBAL slow_query_log = ON;
-- 指定日志文件路径(可选,默认在数据目录)
SET GLOBAL slow_query_log_file = '/var/log/mysql/slow-query.log';
-- 设置慢查询阈值(单位:秒)
SET GLOBAL long_query_time = 2;
-- 记录未使用索引的查询
SET GLOBAL log_queries_not_using_indexes = ON;
2.1.2 永久开启(写入配置文件)
[mysqld]
slow_query_log = ON
slow_query_log_file = /var/log/mysql/slow-query.log
long_query_time = 2
log_queries_not_using_indexes = ON
# 记录管理语句(如 ALTER TABLE)
log_slow_admin_statements = ON
# 记录不使用索引的慢语句(即使未达到 long_query_time)
log_throttle_queries_not_using_indexes = 10
建议:在开发/测试环境开启
log_queries_not_using_indexes,在生产环境谨慎使用,避免日志量过大。建议配合 log_throttle_queries_not_using_indexes 限制每分钟记录条数。
2.2 核心参数详解
| 参数名 | 默认值 | 作用域 | 说明 |
|---|---|---|---|
slow_query_log |
OFF | 全局 | 是否开启慢查询日志 |
long_query_time |
10.000000 | 全局/会话 | 执行时间超过此值的 SQL 被记录(单位:秒,支持微秒) |
log_queries_not_using_indexes |
OFF | 全局 | 是否记录未使用索引的查询(即使执行时间很短) |
log_slow_admin_statements |
OFF | 全局 | 是否记录管理语句(ALTER、CREATE INDEX 等) |
log_throttle_queries_not_using_indexes |
0 | 全局 | 每分钟最多记录多少条未使用索引的查询(0 表示不限制) |
2.3 long_query_time:慢查询的“时间红线”
long_query_time 是判断 SQL 是否为慢查询的核心阈值。MySQL 在查询开始计时,在查询结束后判断执行时间是否超过该值。支持微秒精度,例如 0.5 表示 500 毫秒。
- 单位:秒,支持小数(如 0.1 表示 100ms)
- 作用域:全局和会话级别。会话级别设置仅影响当前连接。
- 注意事项:
- 设置过小(如 0.1)会导致日志量激增,影响磁盘 I/O。
- 设置过大(如 10)会漏掉大量需要优化的查询。
- 建议从 1 秒开始,逐步调低,观察日志量变化。
最佳实践:OLTP 业务建议
long_query_time = 1;报表/批处理业务可设为 2~5;微服务高并发场景可设为 0.5~1。
2.4 log_queries_not_using_indexes:索引缺失的“照妖镜”
该参数用于记录那些没有使用索引的查询,即使它们的执行时间很短。这是发现全表扫描、索引设计缺陷的利器。
- 开启后:所有未使用索引的 SELECT、INSERT、UPDATE、DELETE 都会被记录。
- 风险:如果表结构简单或数据量小,大量短查询也会被记录,导致日志膨胀。
- 配合参数:
log_throttle_queries_not_using_indexes可以限制每分钟记录条数,避免日志风暴。
注意:即使查询使用了索引,如果 MySQL 优化器认为索引效率不高(如索引选择性差),也可能被记录。此时需要检查索引质量,而非仅关注是否使用索引。
2.5 慢查询日志记录流程
下图展示了 MySQL 判断一条 SQL 是否写入慢查询日志的完整流程:
2.6 参数配置对比与建议
| 场景 | long_query_time | log_queries_not_using_indexes | log_throttle | 说明 |
|---|---|---|---|---|
| 开发环境 | 0.5 | ON | 0 | 全面捕获慢 SQL 和索引问题 |
| 测试环境 | 1 | ON | 10 | 限制未使用索引的日志量,避免干扰 |
| 生产环境(保守) | 2 | OFF | - | 仅记录严重慢查询,减少 I/O 开销 |
| 生产环境(优化) | 1 | ON | 5 | 平衡诊断能力与日志量,配合监控告警 |
2.7 验证配置是否生效
-- 查看当前慢查询日志状态
SHOW VARIABLES LIKE 'slow_query_log%';
SHOW VARIABLES LIKE 'long_query_time';
SHOW VARIABLES LIKE 'log_queries_not_using_indexes';
-- 手动触发一条慢查询(用于测试)
SELECT SLEEP(3);
-- 查看日志文件(Linux)
tail -f /var/log/mysql/slow-query.log
-- 查看系统表(MySQL 8.0+)
SELECT * FROM mysql.slow_log ORDER BY start_time DESC LIMIT 5;
提示:使用
mysqldumpslow 工具可以汇总分析慢查询日志,快速找出频率最高、耗时最长的 SQL。