高并发下MySQL慢查询日志是性能问题的实时快照,需激进配置阈值、聚焦毛刺信号、结合Java上下文分析执行计划、按业务语义设计复合索引。

高并发场景下,MySQL慢查询日志不是“可看可不看”的附加项,而是性能问题的实时快照——它直接暴露了流量洪峰中哪些SQL在拖垮数据库。处理关键不在日志本身,而在如何快速定位、精准归因、闭环验证。下面分四步说清楚怎么做。
一、高并发下慢日志配置必须更激进
默认 long_query_time=10 秒完全失效;线上接口超 200ms 就可能引发线程堆积。必须调低阈值,并强制记录未走索引的语句:
- 临时启用(立刻生效,适合压测或突发排查):
SET GLOBAL slow_query_log = 'ON';
SET GLOBAL long_query_time = 0.2;
SET GLOBAL log_queries_not_using_indexes = 'ON';
SET GLOBAL min_examined_row_limit = 100; - 永久配置(推荐上线前就写入 my.cnf 的 [mysqld] 段):
slow_query_log = 1
slow_query_log_file = /var/log/mysql/slow_high_conc.log
long_query_time = 0.2
log_queries_not_using_indexes = 1
log_throttle_queries_not_using_indexes = 10 # 防止日志刷屏
注意:log_throttle_* 参数能限制未走索引语句每分钟最多记几条,避免磁盘被打满。
二、从日志里抓真问题,别被“平均”骗了
高并发下,同一条SQL可能一次快一次慢。单看 Query_time 平均值会漏掉毛刺。重点盯三类信号:
立即学习“Java免费学习笔记(深入)”;
- Rows_examined 远大于 Rows_sent:比如扫描 80 万行只返回 15 条,基本是全表扫描或索引失效;
- Lock_time 显著升高:如 Lock_time: 1.345s,说明锁等待严重,可能是事务过长或热点行争用;
- 同一SQL反复出现但时间波动大:比如某订单查询有时 0.1s,有时 3.2s,大概率是统计信息过时或执行计划抖动。
用 mysqldumpslow -s t -t 20 slow_high_conc.log 按耗时倒序取前 20,再人工过滤掉定时任务类 SQL(如凌晨跑的报表),聚焦用户请求链路中的真实慢点。
三、EXPLAIN 要结合 Java 上下文读
把慢日志里的 SQL 复制出来,前面加 EXPLAIN 执行,但不能只看 type 和 key。Java 层的写法常让执行计划“失真”:
- 参数类型不匹配:MyBatis 传 String 类型 userId,DB 字段是 BIGINT → 隐式转换导致 key 为 NULL;
- LIKE 左模糊:WHERE user_name LIKE '%张%' → type = ALL,哪怕有索引也废;
- 深分页陷阱:ORDER BY create_time LIMIT 10000,20 → Extra 出现 Using filesort + Using temporary,且 Rows_examined 随 offset 增长;
- 函数包裹字段:WHERE DATE(create_time) = '2026-08-20' → 索引失效,应改用 create_time >= '2026-08-20' AND create_time < '2026-08-21'。
特别提醒:MyBatis 的 <if test="xxx != null"> 动态拼接,若条件为空但 SQL 仍含 OR 或额外 WHERE 子句,也可能触发全表扫描。
四、索引优化要带业务语义设计
高并发下,单列索引往往不够。优先建复合索引,并按“等值查询 → 最左前缀 → 范围查询”顺序排列:
- 常见场景:按用户查订单,再按时间范围分页 → 建 INDEX idx_user_time (user_id, create_time);
- 避免冗余:已有 (a,b) 索引,就不用单独建 (a) 索引;
- 覆盖索引提效:SELECT order_no, status FROM orders WHERE user_id = ? AND create_time > ? → 可扩展为 INDEX idx_user_time_cover (user_id, create_time, order_no, status),避免回表;
- 上线前必做:用 ANALYZE TABLE orders; 更新统计信息,防止优化器误判。
索引不是越多越好。高频写入表(如订单流水)上,每个新增索引都会拖慢 INSERT/UPDATE 性能,建议单表索引总数不超过 5~6 个。


















