性能优化
MySQL 性能诊断与优化,包括慢查询日志、EXPLAIN 分析和常见优化策略
语法
SHOW VARIABLES LIKE 'slow_query%'; SET GLOBAL slow_query_log = ON; EXPLAIN [FORMAT=JSON] SELECT ...; SHOW PROCESSLIST;
参数
| 参数 | 说明 | 示例 | 级别 |
|---|---|---|---|
slow_query_log |
开启慢查询日志 | SET GLOBAL slow_query_log = ON; |
常用 |
long_query_time |
慢查询阈值(秒) | SET GLOBAL long_query_time = 1; |
常用 |
EXPLAIN |
分析查询执行计划 | EXPLAIN SELECT * FROM orders WHERE user_id = 1001; |
常用 |
SHOW PROCESSLIST |
查看当前连接和执行中的查询 | SHOW FULL PROCESSLIST; |
常用 |
SHOW STATUS |
查看服务器状态变量 | SHOW GLOBAL STATUS LIKE 'Threads%'; |
进阶 |
示例
开启和查看慢查询日志
-- 开启慢查询日志 SET GLOBAL slow_query_log = ON; SET GLOBAL long_query_time = 1; -- 超过 1 秒记录 SET GLOBAL log_queries_not_using_indexes = ON; -- 记录未使用索引的查询 -- 查看慢查询日志位置 SHOW VARIABLES LIKE 'slow_query_log_file'; -- 用 mysqldumpslow 分析慢查询 -- mysqldumpslow -s t -t 10 /var/log/mysql/slow.log
生产环境建议 long_query_time 设为 1-2 秒
EXPLAIN 分析查询
EXPLAIN SELECT o.order_no, u.username FROM orders o JOIN users u ON o.user_id = u.id WHERE o.status = 1 AND o.created_at > '2026-05-01' ORDER BY o.created_at DESC; -- 关键指标: -- type: ALL(全表扫描) < index < range < ref < const -- key: 实际使用的索引 -- rows: 预估扫描行数(越少越好) -- Extra: Using filesort(需优化) Using temporary(需优化)
type 至少要达到 range 级别,ALL 表示全表扫描需要优化
查找和终止慢查询
-- 查看当前执行中的查询 SHOW FULL PROCESSLIST; -- 找到执行时间过长的查询 SELECT * FROM information_schema.PROCESSLIST WHERE COMMAND != 'Sleep' AND TIME > 10 ORDER BY TIME DESC; -- 终止问题查询 KILL 12345; -- 12345 是进程 ID
紧急情况下可以 KILL 慢查询,但要找到根本原因
常见优化配置
-- 查看 InnoDB 缓冲池大小(建议设为物理内存的 60-80%) SHOW VARIABLES LIKE 'innodb_buffer_pool_size'; -- 查看连接数配置 SHOW VARIABLES LIKE 'max_connections'; SHOW STATUS LIKE 'Threads_connected'; -- 查看表的统计信息 ANALYZE TABLE orders; -- 查看索引使用统计 SELECT * FROM sys.schema_unused_indexes; -- MySQL 8.0+
innodb_buffer_pool_size 是最重要的性能参数
常见错误
查询突然变慢(之前很快)
可能是统计信息过期,执行 ANALYZE TABLE 更新;或数据量增长导致索引失效,需要优化查询或添加索引
Too many connections
连接数耗尽。检查是否有连接泄漏,增加 max_connections,或使用连接池
技巧
- 优化顺序:SQL 优化 > 索引优化 > 架构优化 > 硬件升级
- 定期执行 ANALYZE TABLE 更新统计信息,帮助优化器选择正确的执行计划
- 读写分离:主库写、从库读,是最常见的扩展方案