MySQL CPU占用过高时,应先用top确认是否mysqld进程导致,再通过SHOW PROCESSLIST和EXPLAIN定位低效SQL,最后优化索引、配置及避免函数运算等诱因。
MySQL CPU 占用过高,核心思路是“先定位、再归因、后优化”。重点不是看整体CPU百分比,而是确认是不是 mysqld 进程本身 在消耗CPU,以及它正在执行什么操作。
用 top 或 htop 查看进程级占用:
top -c,关注 %CPU 列,找到 mysqld 对应的 PIDtop -Hp [PID] 查看 mysqld 内部哪些线程最忙(注意 TID)登录 MySQL,快速识别“正在干坏事”的查询:
SHOW FULL PROCESSLIST;,重点关注 State 是 Sending data、Copying to tmp table、Sorting result 或 Creating sort index 的连接SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST WHERE COMMAND != 'Sleep' AND TIME > 2;
KILL [ID] 临时止损(生产环境慎用)CPU 高往往源于低效 SQL,尤其是没走索引、大量排序/分组、子查询嵌套深的语句:
slow_query_log = 1,long_que
ry_time = 2),重启后收集典型负载时段日志EXPLAIN 分析问题 SQL,重点看:type 是否为 ALL(全表扫描)key 是否用了索引Extra 是否含 Using filesort、Using temporary
ORDER BY + LIMIT 无覆盖索引、GROUP BY 字段未建索引、IN (subquery) 未转成 JOIN、WHERE 条件中对字段做函数运算(如 DATE(created_at))有些高 CPU 并非 SQL 本身问题,而是配置不合理放大了开销:
tmp_table_size 和 max_heap_table_size 过小 → 导致频繁磁盘临时表(Copying to tmp table on disk),建议设为 64M~256M(需匹配内存)innodb_buffer_pool_size 过小 → 缓存命中率低,反复读磁盘+解析页,CPU 被 IO 等待掩盖但实际在忙调度Threads_connected 接近 max_connections)→ 线程上下文切换开销剧增SELECT * FROM INFORMATION_SCHEMA.INNODB_TRX; 和 SHOW ENGINE INNODB STATUS; 中的死锁片段