查询变慢但慢查询日志里没记录,通常不是“没慢”,而是慢日志没捕获到——最常见原因是 long_query_time 设置过高(比如默认 10 秒),或者慢日志根本没开、路径写错、权限不足。也可能是查询耗时在阈值边缘反复波动,或被缓存掩盖了真实延迟。
确认慢日志是否真在工作
别只看配置文件写了没,要验证运行时状态:
执行SHOW VARIABLES LIKE 'slow_query_log';—— 必须是
ON,不是
1或空字符串 执行
SHOW VARIABLES LIKE 'long_query_time';—— 线上建议设为
0.5或
1,不是默认 10 执行
SHOW VARIABLES LIKE 'slow_query_log_file';—— 检查路径是否存在、MySQL 进程是否有写权限(如
/var/log/mysql/下目录不可写会导致日志静默失效) 临时触发一条明确的慢 SQL 测试:
SELECT SLEEP(2);,再立刻查日志文件,看是否落盘
绕过日志,实时抓取正在变慢的查询
慢日志是“事后记录”,而
information_schema.processlist是“正在发生”: 运行
SELECT * FROM information_schema.processlist WHERE TIME > 2 AND COMMAND != 'Sleep';,找出已执行超 2 秒还在跑的语句 重点关注
State列:出现
Sorting result、
Sending data、
Copying to tmp table说明卡在排序、结果集传输或临时表阶段 搭配
SHOW ENGINE INNODB STATUS\G查看最近的死锁、锁等待、buffer pool 命中率,常能发现隐性瓶颈
检查是不是被缓存干扰了判断
查询“变慢”有时是缓存失效导致的突变,而非 SQL 本身劣化:
执行SELECT @@query_cache_type, @@query_cache_size;(MySQL 5.7 及以前)或
SELECT @@performance_schema;(8.0+),确认是否启用了可能误导判断的旧机制 用
SELECT SQL_NO_CACHE ...强制跳过查询缓存(5.7 及以前),或在 8.0+ 中关闭
query_cache_type=0对比首次执行和重复执行耗时:如果首次很慢、后续极快,大概率是 buffer pool 未预热或磁盘冷读导致
从系统层反向定位 IO 或资源瓶颈
MySQL 慢,不一定是 SQL 的问题:
终端运行top,观察
%CPU和
%MEM是否打满;若
wa(iowait)持续 >20%,说明磁盘在拖后腿 执行
iostat -x 1,重点看
%util(接近 100% 表示磁盘饱和)、
await(单次 IO 平均等待毫秒,>10ms 就需警惕) 用
df -h检查数据盘是否剩余空间 查连接数:
SHOW STATUS LIKE 'Threads_connected';,若接近
max_connections上限,新查询会排队等待
