当WordPress导致MySQL CPU占用过高时,通常是由于某些SQL查询执行效率低下或频繁执行所致。以下是系统化的排查方法:
1. 启用MySQL慢查询日志(Slow Query Log)
这是最直接的诊断方式。
配置步骤:
编辑 MySQL 配置文件(如 my.cnf 或 mysqld.cnf):
[mysqld]
slow_query_log = 1
slow_query_log_file = /var/log/mysql/mysql-slow.log
long_query_time = 1
log_queries_not_using_indexes = 1
long_query_time = 1:记录执行时间超过1秒的查询。log_queries_not_using_indexes:记录未使用索引的查询。
重启 MySQL 并测试访问网站后查看日志:
sudo tail -f /var/log/mysql/mysql-slow.log
2. 使用 SHOW PROCESSLIST 实时监控活跃查询
登录 MySQL,查看当前正在运行的查询:
SHOW FULL PROCESSLIST;
重点关注:
Time列:执行时间长的查询。State列:如 “Sending data”, “Copying to tmp table” 表示可能性能问题。Info列:具体的 SQL 语句。
可配合脚本定期检查:
mysql -e "SHOW FULL PROCESSLIST;" | grep -v Sleep
3. 使用 Performance Schema 分析(MySQL 5.6+)
启用 performance_schema 查看耗时最高的语句:
-- 查看执行次数最多、耗时最长的语句
SELECT
DIGEST_TEXT,
COUNT_STAR,
SUM_TIMER_WAIT / 1000000000 AS total_sec,
AVG_TIMER_WAIT / 1000000000 AS avg_sec
FROM performance_schema.events_statements_summary_by_digest
ORDER BY SUM_TIMER_WAIT DESC
LIMIT 10;
注意:部分 WordPress 查询会带有占位符(如 wp_posts.ID = ?),需结合上下文判断来源。
4. 结合 WordPress 插件或代码调试
方法一:启用 SAVEQUERIES
在 wp-config.php 中开启查询记录:
define('SAVEQUERIES', true);
在页面底部输出最耗时的查询:
if (defined('SAVEQUERIES') && SAVEQUERIES) {
$queries = $wpdb->queries;
foreach ($queries as $query) {
if ($query[1] > 0.5) { // 耗时超过0.5秒
echo "<pre>Query: {$query[0]} | Time: {$query[1]}</pre>";
}
}
}
⚠️ 仅用于开发环境,生产环境禁用。
方法二:使用调试插件
- Query Monitor(推荐)
- 显示每页所有SQL查询、执行时间、调用堆栈。
- 可定位是哪个插件或主题函数发起的慢查询。
5. 常见高CPU查询来源及优化建议
| 问题类型 | 典型查询 | 解决方案 |
|---|---|---|
| 缺少索引 | SELECT * FROM wp_postmeta WHERE meta_key = '...' |
为 meta_key 添加索引 |
| 大量 JOIN | 多表关联无限制 | 减少不必要的JOIN,分页处理 |
| 无限循环查询 | 每次循环执行一次数据库查询 | 使用缓存或批量查询 |
| 未分页的获取 | get_posts() 无 numberposts 限制 |
设置合理数量或分页 |
| 插件问题 | 如SEO、缓存、统计类插件频繁更新数据 | 替换低效插件 |
6. 优化建议汇总
-
添加必要索引
ALTER TABLE wp_postmeta ADD INDEX meta_key_index (meta_key); ALTER TABLE wp_term_relationships ADD INDEX object_id_index (object_id); -
启用对象缓存
使用 Redis 或 Memcached 缓存数据库查询结果。 -
定期清理数据
删除无用的修订版、垃圾评论、过期 transients:DELETE FROM wp_posts WHERE post_type = 'revision'; DELETE FROM wp_options WHERE option_name LIKE '_transient_%' AND option_value < NOW() - INTERVAL 1 DAY; -
使用OPcache和页面缓存
减少PHP解析和数据库请求。 -
升级硬件或调整MySQL配置
如增加innodb_buffer_pool_size,优化查询缓存等。
总结流程图
高CPU → 开启慢查询日志 → 定位慢SQL
↓
分析来源(插件/主题)
↓
优化SQL + 添加索引 + 启用缓存
↓
监控效果,持续调优
通过以上方法,通常可以精准定位并解决 WordPress 导致 MySQL 高CPU的问题。建议优先使用 Query Monitor 插件 + 慢查询日志 组合排查。
云小栈