数据库体检发现 wp_postmeta 已经四十多万行 文章才八千篇 随便查一个 meta_key 都能翻出大量 post_id 早就不存在的记录 看着像数据没删干净。乍看像缓存或者权限的锅,追下去往往不是。
SELECT COUNT(*) FROM wp_postmeta pm LEFT JOIN wp_posts p ON pm.post_id=p.ID WHERE p.ID IS NULL; DELETE pm FROM wp_postmeta pm LEFT JOIN wp_posts p ON pm.post_id=p.ID WHERE p.ID IS NULL;
追下去是这么回事:删除文章时用的是直接 DELETE wp_posts 没有走 wp_delete_post 挂在它下面的 postmeta 没人清理 一次次导入又叠了一层 现在连主表都对不上 之前的清理脚本也漏了。
「孤儿 postmeta 清理」相关的日志我一般连着看前后五分钟,单看一条报错经常判断不出是哪一步失败。接口问题先分清是没发出去、发出去了没收到,还是收到了处理失败。
偶发问题先统计频率,一小时几次和一天一次,查法完全不同。
具体做法是,先跑一条 LEFT JOIN 统计孤儿行数 确认量级和影响范围再动手;删之前把要删的 post_id 导出一份 出问题还能对照恢复;清理完顺手给 wp_postmeta 加上 post_id 索引 后面的查询才不会每次全表扫。
验收就看一点,孤儿行数归零 文章页读取自定义字段不再扫整张表 明显变快。
