# MySQL 慢查询与连接数排查 ## 场景 应用变慢、接口超时,DBA 说数据库没问题,但 `show processlist` 里一堆 `Sending data`。 ## 前置条件 - 有 root 或监控权限 - 知道业务高峰时段 - 能改配置并重启(或动态设置) ## 配置 开启慢日志(8.0 动态生效): ```sql SET GLOBAL slow_query_log = ON; SET GLOBAL long_query_time = 1; SET GLOBAL log_output = 'FILE'; SHOW VARIABLES LIKE 'slow_query_log_file'; ``` 排查连接: ```sql SHOW STATUS LIKE 'Threads_connected'; SHOW STATUS LIKE 'Max_used_connections'; SHOW VARIABLES LIKE 'max_connections'; SHOW PROCESSLIST; ``` 看谁在等锁: ```sql SELECT * FROM performance_schema.data_locks; SELECT * FROM sys.innodb_lock_waits; ``` 分析慢日志: ```bash mysqldumpslow -s t -t 20 /var/lib/mysql/slow.log # 或 pt-query-digest /var/lib/mysql/slow.log | head -60 ``` ## 验证 ```sql EXPLAIN SELECT ...; -- 看是否走索引 SHOW PROFILE FOR QUERY 1; -- 8.0 用 performance_schema ``` ## 回滚 ```sql SET GLOBAL long_query_time = 10; SET GLOBAL slow_query_log = OFF; ``` ## 坑 - **`max_connections` 调大不一定有用**,连接多了内存和上下文切换更糟。 - 慢日志开了但 `long_query_time` 还是默认 10 秒,等于没开。 - `Sending data` 不代表在传数据,多数时候是在扫表。 - 没有索引的 `LIKE '%xx%'` 一定全表扫。 - 事务没提交会一直持锁,`SHOW ENGINE INNODB STATUS` 里能看到。 - 改 `innodb_buffer_pool_size` 要重启,别在业务高峰做。