织梦数据库压缩优化方法

织梦 DedeCMS 用得越久,数据库越臃肿:几万篇文章之后,dede_addonarticle 单表就可能上百 MB,后台打开缓慢、生成 HTML 卡顿。数据库"压缩"本质上是回收已删除数据留下的碎片、清理冗余记录、优化表结构。下面给出完整方案。

一、数据库为什么越用越大

1. DELETE 留下碎片

MySQL 的 InnoDB/MyISAM 在 DELETE 后并不会真正释放磁盘空间,而是把空间标记为可复用,导致 .ibd/.MYD 文件持续膨胀。

2. dede_archives 与 dede_addonarticle 重复字段

主表 dede_archives 存基础信息,附加表 dede_addonarticle 存正文,两者都有 id、typeid 等字段,迁移/删除时容易产生孤儿记录。

3. 日志类表无限增长

dede_logdede_search_keywordsdede_purviewdede_member_feed 是日志性质,长期不清理会拖慢查询。

4. 缩略图、附件表冗余

文章删除后 dede_uploads 里的记录常常没被清掉,残留大量"幽灵"附件记录。

二、第一步:清理冗余数据

1. 清空日志类表

TRUNCATE TABLE dede_log;
TRUNCATE TABLE dede_search_keywords;
TRUNCATE TABLE dede_purview;

2. 删除已删文章残留的附件记录

DELETE FROM dede_uploads WHERE arcid NOT IN (SELECT id FROM dede_archives);

3. 删除已删文章的附加表数据

DELETE FROM dede_addonarticle WHERE aid NOT IN (SELECT id FROM dede_archives);
DELETE FROM dede_addonimages WHERE aid NOT IN (SELECT id FROM dede_archives);
DELETE FROM dede_arctiny WHERE id NOT IN (SELECT id FROM dede_archives);

4. 删除过期未审核文章

DELETE FROM dede_archives WHERE arcrank=-2 AND senddate < UNIX_TIMESTAMP()-86400*30;
提醒:所有 DELETE 语句执行前都先 SELECT COUNT(*) 看影响行数,确认无误再删。

三、第二步:OPTIMIZE TABLE 回收空间

清理完数据后,物理空间仍未释放,需要对每张表执行 OPTIMIZE:

OPTIMIZE TABLE dede_archives;
OPTIMIZE TABLE dede_addonarticle;
OPTIMIZE TABLE dede_uploads;
OPTIMIZE TABLE dede_arctiny;
OPTIMIZE TABLE dede_log;

或者一次优化整库(命令行):

mysqlcheck -o -uroot -p dedecms

InnoDB 表在 MySQL 5.6.17+ 支持 inplace 优化;旧版需要先 ALTER TABLE xxx ENGINE=InnoDB; 重建。

四、第三步:精简表结构

1. 去掉不用的附加字段

后台 → 核心 → 内容模型管理 → 字段管理,删除长期不使用的自定义字段,对应 dede_addonarticle 中的列也会被清掉。

2. 把长字段改短

正文表 body 用 longtext 通常没必要,改成 mediumtext 可省一半空间:

ALTER TABLE dede_addonarticle MODIFY body MEDIUMTEXT;

3. 给常用查询字段加索引

ALTER TABLE dede_archives ADD INDEX idx_typeid_senddate(typeid,senddate);
ALTER TABLE dede_archives ADD INDEX idx_flag_senddate(flag,senddate);

五、第四步:分表与归档

文章超过 10 万的站点,建议按年份归档老文章到独立表,主表只保留近 1 年数据。可以用织梦的"内容模型"功能实现,或自行写脚本把 senddate 小于阈值的数据搬到 archive_2022、archive_2023 等表。

六、注意事项

1. OPTIMIZE 期间表会被锁定,大表请在凌晨低峰期执行。

2. 执行前一定 mysqldump 全库备份,OPTIMIZE 过程中如果断电可能损坏表。

3. 不要随手对 session、cache 类表加索引,反而会拖慢写入。

4. dede_arccache、dede_mytag 等缓存表定期 TRUNCATE 即可,无需 OPTIMIZE。

5. 优化完成后记得 ANALYZE TABLE 更新统计信息,让查询优化器重新选索引。

风险提醒:大表 ALTER/OPTIMIZE 时务必预留 1.5 倍磁盘空间,否则可能因空间不足导致表损坏。

织梦数据库压缩优化的核心是"先清后压再加索引"——清掉无用的日志、孤儿记录和冗余附件,用 OPTIMIZE TABLE 回收物理空间,最后给热点查询字段加上合适索引。建议把这套流程写成脚本每月执行一次,配合 zabbix 监控表大小,数据库体积异常增长时能第一时间发现。把日志类表设为定期 TRUNCATE 的定时任务,是从源头控制数据库膨胀最有效的动作。