帝国 CMS 数据库查询优化

域名注册
域名注册 正式会员超兽战士 👑年卡会员
发布于 2026-10-08 13:57 ·1 浏览 ·0 回复

照着这篇做完,你能把帝国 CMS 的页面生成时间从两三秒压到一秒以内,并且知道以后慢了该从哪里下手排查。

帝国 CMS 的性能问题九成出在数据库上:信息表(phome_ecms_news 这类)动辄几十万行,栏目页一刷新就是全表扫描。下面按"先测、再改、后验证"的顺序走一遍。

第一步:先找到慢在哪,别瞎改配置

这一步的目标是拿到具体的慢 SQL,而不是凭感觉调参数。最直接的办法是开 MySQL 慢查询日志。

宝塔面板用户:进 软件商店 → MySQL 8.0 → 配置修改,找到 slow_query_log,改成 slow_query_log = On、long_query_time = 1,保存后重载配置,日志在 /www/server/data/mysql-slow.log,跑一天再回来看。

命令行方式:

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

拿到可疑 SQL 后,前面加 EXPLAIN 看执行计划,重点看 type 和 rows 两列:

EXPLAIN SELECT id,title,newstime FROM phome_ecms_news WHERE classid=5 ORDER BY newstime DESC LIMIT 10;

type 出现 ALL 就是全表扫描,rows 接近总行数就是没走索引——这就是你要动刀的地方。

注意:帝国 CMS 默认用的是 MyISAM 引擎,慢查询日志里会混入大量后台自己的管理 SQL,别把"后台刷新页面"的慢查询当成前台问题。

第二步:给信息表补组合索引

大部分慢查询来自栏目页列表,条件是"某栏目 + 按时间倒序",这正好是一个组合索引能解决的。先看现有索引,避免重复添加:

SHOW INDEX FROM phome_ecms_news;

帝国 CMS 默认只给了 classid 和 newstime 两个单列索引,MySQL 只能二选一。补一个组合索引:

ALTER TABLE phome_ecms_news ADD INDEX idx_class_newstime (classid, newstime);

加完再用第一步的 EXPLAIN 跑一遍,rows 应该从几万掉到几十。

注意:几十万行以上的 MyISAM 表执行 ALTER TABLE 会锁表,务必在凌晨低峰做;条件允许先把表转成 InnoDB(ALTER TABLE phome_ecms_news ENGINE=InnoDB;),之后再加索引可以带 ALGORITHM=INPLACE, LOCK=NONE,不阻塞读写。

第三步:用副表把大字段拆出去

帝国 CMS 的信息表把正文 newstext 和标题、时间放在同一张表里,而正文是 TEXT 大字段。列表页只需要标题和时间,却被迫读整行,I/O 白白浪费。帝国 CMS 自带副表机制专治这个。

进后台 系统 → 数据表管理 → 管理数据表,找到你的信息表(如"新闻系统数据表 phome_ecms_news"),点右侧"修改",在表设置里找到副表数量,填 3 到 5,提交。系统会把正文按 id % 副表数 拆到 phome_ecms_news_data_1、_2…… 之后列表查询只碰主表,速度立竿见影。

注意:拆副表会重建数据,操作前先用 系统 → 数据表管理 → 备份数据表 全量备份一次,别省这一步。

第四步:清垃圾、整理碎片

MyISAM 表频繁增删后会产生空洞,OPTIMIZE TABLE 可以回收空间并重建索引:

OPTIMIZE TABLE phome_ecms_news;

顺手清理两类垃圾:后台 信息管理 → 回收站 里彻底清空已删信息;phome_enewslog、phome_enewsloginfail 这类日志表可以直接 TRUNCATE,它们对前台毫无用处。

第五步:减少动态查询——缓存和静态化

数据库改完,还要让查询次数降下来。帝国 CMS 本身是静态化 CMS,别让它跑动态。

后台 系统 → 系统设置 → 系统参数设置,切到性能相关标签页,把信息页、列表页的缓存时间设成 3600 秒以上;再到 系统 → 数据更新中心,依次执行"刷新所有信息内容页面""刷新所有列表页面""刷新首页",让前台直接读 HTML。

模板里的灵动标签 [e:loop] 一定要写 row='10',不写条数上限的标签会拖垮整页。

第六步:调 MySQL 服务端参数

如果表已经转成 InnoDB,在 软件商店 → MySQL → 配置修改 里调整:

  • innodb_buffer_pool_size:设为服务器物理内存的 50%~70%
  • tmp_table_size 和 max_heap_table_size:都设 64M,减少磁盘临时表
  • 仍是 MyISAM 的表,重点调 key_buffer_size,设 256M 左右

改完保存并重启 MySQL。

注意:innodb_buffer_pool_size 一次别调太高,要和 PHP-FPM、Nginx 抢内存,先看服务器剩余可用内存再定。

小结

  • 先开慢查询日志 + EXPLAIN 定位,再动手改,别凭感觉调参数
  • 给信息表补 (classid, newstime) 组合索引,是收益最大的一步
  • 用帝国自带副表机制把 newstext 拆走,列表页只读主表
  • OPTIMIZE TABLE 整理碎片,清空回收站和无用日志表
  • 后台开启页面缓存 + 刷新静态页,把动态查询变成读 HTML
  • MySQL 参数只调 innodb_buffer_pool_size、key_buffer_size 这几个关键的
版权声明:本文来自 GJ站长论坛《帝国 CMS 数据库查询优化》
原文链接:https://www.gj0.com/thread-988.html
转载请注明出处并保留本声明;内容仅代表作者观点,与本站立场无关。若本文涉嫌侵权,请联系本站处理。

全部回复 0

还没有回复,来抢沙发~