一句话结论:WordPress 变慢,八成不是 PHP 慢,而是 wp_options 表里堆了大量 autoload=’yes’ 的垃圾数据、过期 transient 从不清理、文章修订版本无限膨胀。按”查 autoload 体积 → 清过期 transient → 控修订版本 → 补索引”四步处理,多数站点能在半小时内把首字节时间降一个量级。
一、先量:找到真正拖慢你的那张表
别一上来就装优化插件。先用一条 SQL 定位问题规模:
-- 1. autoload 数据总量(超过 800KB 就该处理)
SELECT SUM(LENGTH(option_value)) AS autoload_bytes
FROM wp_options WHERE autoload = 'yes';
-- 2. 体积最大的前 20 条 autoload 数据
SELECT option_name, LENGTH(option_value) AS size
FROM wp_options WHERE autoload = 'yes'
ORDER BY size DESC LIMIT 20;
-- 3. 过期 transient 数量
SELECT COUNT(*) FROM wp_options
WHERE option_name LIKE '_transient_timeout_%'
AND option_value < UNIX_TIMESTAMP();
| 指标 | 健康 | 需要处理 | 危险 |
|---|---|---|---|
| autoload 总量 | < 300KB | 300KB~1MB | > 1MB |
| 过期 transient | < 50 条 | 50~500 条 | > 500 条 |
| 文章修订版本数 | < 100 | 100~1000 | > 1000 |
二、清:过期 transient 与僵尸 option
Transients API 是 WordPress 的临时缓存机制,数据存在 wp_options 里。问题在于:过期记录不会自动消失,只有下次访问到才可能被顺带删掉;而很多插件卸载时也不清理,留下成百上千条 _transient_timeout_* 和对应的 _transient_*。
- 备份。用 WP-CLI 执行 wp db export backup.sql,或在面板里导出一份完整 SQL,任何删除操作前都必须做这一步。
- 清过期 transient:命令行执行 wp transient delete –expired;没有 WP-CLI 就调用核心函数 delete_expired_transients(true)。
- 查并清理僵尸 autoload 项:按上面的 SQL 找出体积异常且属于已卸载插件的 option,确认无用后 DELETE 。
- 限制文章修订版本:在 wp-config.php 加 define(‘WP_POST_REVISIONS’, 5); 只保留最近 5 个版本,或直接设 false 关闭。
- 清理历史修订:执行 DELETE FROM wp_posts WHERE post_type = ‘revision’;(已限制新增后,历史的一次性清掉即可)。
- 清理回收站:wp post delete $(wp post list –post_status=trash –format=ids) 或把 EMPTY_TRASH_DAYS 设小。
没有 WP-CLI 怎么清过期 transient?
三、防:三个让问题不再复发的设置
1. 始终给 transient 设过期时间
这是个隐蔽的坑:set_transient('key', $value) 不传过期时间时,核心源码里会把 autoload 设为 ‘yes’。也就是说这条”临时”数据会被每次页面加载都读一遍。哪怕只设 1 秒,autoload 也会变成 ‘no’。
// 反例:会 autoload,每次请求都加载
set_transient( 'my_cache', $data );
// 正例:设过期时间,不进 autoload
set_transient( 'my_cache', $data, 3600 );
2. 上持久化对象缓存
装了 Redis / Memcached 这类持久对象缓存后,transient 不再落库,而是走内存;速度提升的同时,wp_options 表也不会再被撑大。这是从根上解决问题的方案,需要服务器侧配合(装扩展 + 放 object-cache.php drop-in)。
3. 控制自动加载的规模
写插件/主题时,除非选项真的每页都要用,否则 add_option() 的第四个参数传 ‘no’;能用 wp_cache_set() 解决的页内复用,就不要写进数据库。
四、补索引与表维护
数据量上来后,缺索引是另一类隐形杀手。高频查询字段(如 postmeta 的 meta_key 、 options 的 autoload)应有索引。可以定期跑 OPTIMIZE TABLE 回收碎片(InnoDB 上效果有限,但清理完大量数据后跑一次仍有意义)。
五、常见误区
- 装了缓存插件就以为数据库不用管——页面缓存只挡住前端请求,后台和动态接口照样慢;
- 直接清空整张 wp_options——里面有站点 URL 、活动插件等核心配置,删错直接白屏;
- 把优化做成一次性动作——不加 WP_POST_REVISIONS 限制、不给 transient 设过期,半年后照旧;
- 不看 autoload 只看表体积——一张 200MB 的表如果查询都走索引,可能比一条 2MB 的 autoload option 快得多。
配套阅读:WordPress 速度优化实测;站点整体安全与权限检查另见 WordPress 安全加固清单。
阅读官方 Transients API 文档








评论 (0)