帝国 CMS 数据库怎么优化
照着做完这套流程,你能把帝国 CMS 的数据库体积压下来、后台列表页打开速度提上去,并且留下一套每月可重复执行的维护动作。
第一步:先备份,再动任何一条 SQL
这一步的目标是——万一后面删错表、加错索引,你能在 10 分钟内恢复原样。
登录帝国 CMS 后台,顶部菜单点「系统」→「备份与恢复数据」→「备份数据」,勾选「备份全部数据表」,压缩方式选「Gzip」,点「开始备份」。备份文件默认落在 /e/data/backupdata/ 目录下。
注意:这个目录如果在 Web 根目录内且没做防护,别人猜不到路径也能拖走整个库。备份完立刻把它下载到本地,然后删掉服务器上的备份文件,或者在 Nginx 里加一条
location ^~ /e/data/backupdata/ { deny all; }。
更稳的做法是命令行备份:
mysqldump -uroot -p --single-transaction --default-character-set=utf8 你的库名 > /data/backup/empire_$(date +%F).sql
第二步:摸清哪张表最占地、碎片最多
这一步的目标是——找出真正的"胖子",避免瞎优化。
先跑这条查询(把库名换成你自己的):
SELECT table_name, table_rows,
ROUND(data_length/1024/1024,1) AS data_mb,
ROUND(index_length/1024/1024,1) AS index_mb,
ROUND(data_free/1024/1024,1) AS free_mb
FROM information_schema.tables
WHERE table_schema='你的库名'
ORDER BY data_length DESC LIMIT 20;
free_mb 那一列就是碎片占用。帝国 CMS 的库通常这几张表最容易膨胀:phome_ecms_news、phome_ecms_news_data_1、phome_enewslog(后台操作日志)、phome_enewsmember(会员)、phome_ecms_infotmp_*(采集临时表)。
注意:表名以
phome_开头是默认前缀,如果你装站时改过,用SHOW TABLES LIKE '%news%';确认一下真实表名再操作。
第三步:清掉不值得留的数据
这一步的目标是——把"垃圾体积"直接从库里删掉。
后台「信息」→「回收站管理」,点「清空回收站」,这一步会真正删除被删文章及其附属数据。
采集临时表如果不用采集功能,可以直接清空:
TRUNCATE TABLE phome_ecms_infotmp_1;
后台日志保留 30 天就够:
DELETE FROM phome_enewslog WHERE logtime < UNIX_TIMESTAMP(DATE_SUB(NOW(), INTERVAL 30 DAY));
注意:
DELETE删完不会自动释放磁盘空间,必须配合第四步的OPTIMIZE TABLE才真正瘦身。另外删日志前确认字段名是logtime,不同版本可能叫logtime或dotime,用DESC phome_enewslog;看一眼。
第四步:回收碎片空间
这一步的目标是——把删数据留下的空洞还回磁盘,顺便重建索引。
后台「系统」→「备份与恢复数据」→「优化数据表」,勾选所有表,点「开始优化」。
命令行等价操作:
OPTIMIZE TABLE phome_ecms_news, phome_ecms_news_data_1, phome_enewslog;
注意:大表(几百万行以上)执行时会锁表,前台可能短暂 502。建议凌晨执行。InnoDB 表如果空间紧张,
OPTIMIZE需要额外磁盘空间,先确认剩余空间大于表体积。
第五步:给高频查询补索引
这一步的目标是——让栏目页、列表页的 SQL 走索引,不再全表扫描。
先用 EXPLAIN 看现状:
EXPLAIN SELECT * FROM phome_ecms_news WHERE classid=1 AND checked=1 ORDER BY newstime DESC LIMIT 20;
如果 type 是 ALL,说明在扫全表,补组合索引:
ALTER TABLE phome_ecms_news ADD INDEX idx_class_checked_time (classid, checked, newstime);
注意:加索引前先跑
SHOW INDEX FROM phome_ecms_news;,如果已经有(classid, newstime)这类前缀相同的索引,就不要重复加,否则写入会更慢。
第六步:调 MySQL 配置和后台参数
这一步的目标是——让数据库本身跑得更快。
编辑 /etc/my.cnf(或 /etc/mysql/my.cnf)的 [mysqld] 段:
innodb_buffer_pool_size = 2G # 有独立数据库服务器时,给物理内存的 50%~70%
innodb_log_file_size = 256M
max_connections = 300
改完 systemctl restart mysqld。MySQL 8.0 已经移除了查询缓存,网上让你开 query_cache_size 的老教程不要照抄。
后台再去「系统」→「系统设置」→「系统参数设置」→「性能优化参数」,把前台不用的功能(如访问统计、在线人数)关掉,减少写入。
第七步:挂成定时任务
这一步的目标是——以后不用手动做,每月自动跑。
后台「系统」→「计划任务」→「增加计划任务」,设置每月 1 日凌晨 4 点执行一次优化。或者在 Linux 的 crontab 里加:
0 4 1 * * mysql -uroot -p密码 你的库名 -e "OPTIMIZE TABLE phome_ecms_news, phome_ecms_news_data_1;"
小结
- 任何优化动作之前,先备份,并且把备份文件挪出 Web 目录。
- 用
information_schema.tables找出最占地的表和碎片量,别凭感觉优化。 - 回收站、采集临时表、30 天以前的日志是主要垃圾来源。
DELETE之后必须OPTIMIZE TABLE,空间才真的还回去。- 索引只加在
EXPLAIN显示全表扫描的高频查询上,加多了反而拖慢写入。 - MySQL 8.0 别再配 query_cache;缓冲区大小按内存比例给。
- 最后把优化写进计划任务或 crontab,让它自动跑。
原文链接:https://www.gj0.com/thread-896.html
转载请注明出处并保留本声明;内容仅代表作者观点,与本站立场无关。若本文涉嫌侵权,请联系本站处理。