性能优化

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,或使用连接池

技巧

相关命令