报错是这么冒出来的。文章页首字节 1.4 秒,LCP 3.6 秒,慢日志里同一段 SQL 每次执行 1.1 秒,是首页推荐位的随机取数查询。

中间走过弯路,把「对象缓存未命中,每次请求都回数据库」当成主因,改完现象没变。

排查方向其实有限,先把可能性排一排。ORDER BY RAND() 在十万行表上全表扫描。还有一种是查询没走索引,postmeta 的 join 条件被函数包裹。

不容易想到的是,PHP-FPM 进程数不足,排队等待拉长首字节时间。

动手时先打开慢查询日志定位语句

SET GLOBAL slow_query_log=1; SET GLOBAL long_query_time=1;

随后看执行计划是否走索引

EXPLAIN SELECT ID FROM wp_posts ORDER BY RAND() LIMIT 6;

再往下改成按时间倒序取数

SELECT ID FROM wp_posts WHERE post_status='publish' ORDER BY post_date DESC LIMIT 6;

给查询结果加对象缓存

wp cache set hot_posts "$(wp db query 'SELECT ID FROM wp_posts LIMIT 6')" 300

报错是间歇性的,我蹲守了半小时才抓到一次完整现场。

别只看报错消失,验证要多做一步。TTFB 降到 400ms 以内,LCP 同步落到 2.5 秒以下,慢查询日志里不再出现持续一秒以上的语句。

TTFB 不直接计入 LCP,但它是 LCP 的起点,后端慢一秒前端优化全白做。改动前把原配置备份一份,出问题能马上回滚,这比任何技巧都实用。

作者 9823189