如何排查WordPress导致MySQL CPU占用过高的具体查询?

云计算

当 WordPress 导致 MySQL CPU 占用过高时,通常是由于某些 SQL 查询执行效率低下、频繁执行或未正确使用索引。以下是系统性的排查方法:


一、确认问题来源:MySQL 是否真的高负载?

  1. 查看服务器整体负载

    top
    # 或
    htop

    观察 mysqld 进程的 CPU 使用率。

  2. 查看 MySQL 当前状态

    mysqladmin -u root -p processlist

    或登录 MySQL 后运行:

    SHOW FULL PROCESSLIST;

    查看是否有大量长时间运行的查询(StateSending data, Copying to tmp table 等)。


二、启用慢查询日志(Slow Query Log)

这是定位低效查询的关键工具。

1. 开启慢查询日志

编辑 MySQL 配置文件(如 /etc/mysql/my.cnf/etc/my.cnf):

[mysqld]
slow_query_log = 1
slow_query_log_file = /var/log/mysql/slow.log
long_query_time = 1
log_queries_not_using_indexes = 1
  • long_query_time = 1:记录超过 1 秒的查询(可调低到 0.5 或 0.1)
  • log_queries_not_using_indexes = 1:记录未使用索引的查询

重启 MySQL 生效:

sudo systemctl restart mysql

2. 分析慢查询日志

使用 mysqldumpslow 工具分析:

mysqldumpslow /var/log/mysql/slow.log

常用命令:

# 按查询时间排序,显示前10条最慢的查询
mysqldumpslow -s at -t 10 /var/log/mysql/slow.log

# 按锁等待时间排序
mysqldumpslow -s al -t 10 /var/log/mysql/slow.log

也可使用更强大的工具如 pt-query-digest(Percona Toolkit):

pt-query-digest /var/log/mysql/slow.log

三、使用 Performance Schema(MySQL 5.6+)

启用 Performance Schema 可深入分析查询性能:

-- 查看是否开启
SHOW VARIABLES LIKE 'performance_schema';

-- 查看最耗资源的 SQL 语句
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
WHERE DIGEST_TEXT LIKE '%wp_%'
ORDER BY SUM_TIMER_WAIT DESC
LIMIT 10;

注意:首次使用可能需要先启用收集:

UPDATE performance_schema.setup_consumers SET ENABLED = 'YES' WHERE NAME LIKE 'events_statements%';

四、WordPress 层面排查常见问题查询

常见导致高负载的 WordPress 查询类型:

  1. 未优化的 meta_query / tax_query

    SELECT * FROM wp_postmeta WHERE meta_key = 'some_key';

    → 缺少对 meta_key 的索引(默认有,但大数据量仍慢)

  2. 无索引的 JOIN 查询

    SELECT ... FROM wp_posts LEFT JOIN wp_postmeta ...

    → 多个 JOIN 和 WHERE 条件未走索引

  3. 插件造成的 N+1 查询

    • 如某些 SEO 插件、缓存插件、表单插件会在循环中执行数据库查询
  4. 无限文章分页或全表扫描

    SELECT SQL_CALC_FOUND_ROWS ... LIMIT ...

    SQL_CALC_FOUND_ROWS 在大数据集上非常慢


五、使用 WordPress 调试工具

1. 启用 SAVEQUERIES

wp-config.php 中添加:

define('SAVEQUERIES', true);

在页面底部输出查询统计:

global $wpdb;
foreach ($wpdb->queries as $query) {
    printf("%s (%s sec)n", $query[0], $query[1]);
}

2. 使用 Query Monitor 插件

  • 安装 Query Monitor
  • 实时查看每个页面执行的 SQL 查询
  • 显示慢查询、重复查询、未使用索引的查询
  • 支持按执行时间排序,精准定位瓶颈

六、优化建议

  1. 为常用字段加索引

    ALTER TABLE wp_postmeta ADD INDEX idx_meta_key (meta_key);
    ALTER TABLE wp_term_relationships ADD INDEX idx_object_id (object_id);
  2. 避免使用 SQL_CALC_FOUND_ROWS

    • 使用 found_posts 缓存或手动计数
  3. 优化插件

    • 禁用不必要的插件
    • 替换低效插件(如用 WP Super Cache 替代低效缓存插件)
  4. 启用对象缓存

    • 使用 Redis 或 Memcached 减少数据库压力
  5. 定期清理数据

    • 清理 wp_options 中的 transient
    • 删除垃圾评论、旧修订版:
      DELETE FROM wp_posts WHERE post_type = 'revision';

七、监控与预防

  • 使用 New RelicPM2Prometheus + Grafana 监控 MySQL 性能
  • 设置告警:当 MySQL CPU > 80% 持续 5 分钟时通知
  • 定期运行 pt-query-digest 分析慢日志

总结排查流程:

1. 确认 MySQL CPU 高 → 2. 查看 PROCESSLIST → 3. 开启慢查询日志 → 
4. 用 pt-query-digest 分析 → 5. 结合 Query Monitor 定位 WordPress 页面 → 
6. 优化 SQL 或插件 → 7. 添加索引/缓存 → 8. 验证效果

通过以上步骤,可以精准定位是哪个 WordPress 页面或插件触发了低效 SQL,从而有效降低 MySQL CPU 负载。

未经允许不得转载:CLOUD云枢 » 如何排查WordPress导致MySQL CPU占用过高的具体查询?