帝国 CMS 数据库索引优化

juming
juming 初级会员超兽战士
发布于 2026-10-08 12:08 ·1 浏览 ·0 回复

学完这篇,你能自己在帝国 CMS 上定位到拖慢网站的那几条 SQL,并用索引把它们从几秒压到几十毫秒。

第一步:先确认瓶颈真的在数据库

这一步要拿到证据,证明「慢」是数据库造成的,而不是 PHP 或网络。

登录服务器,编辑 MySQL 配置文件(Linux 通常是 /etc/my.cnf,宝塔面板在「数据库 → 配置修改」里也能改),在 [mysqld] 段加入:

slow_query_log = 1
long_query_time = 1
slow_query_log_file = /var/log/mysql-slow.log

改完执行 systemctl restart mysqld(或 service mysql restart)重启 MySQL。

注意:long_query_time 先设 1 秒,跑两三天看看。直接设 0.1 秒会记下大量正常查询,日志反而没法看。

第二步:从慢查询日志里挑出高频 SQL

这一步筛出「出现次数最多 + 耗时最长」的那几条,它们才是优化目标。

等日志攒够量后执行:

mysqldumpslow -s t -t 20 /var/log/mysql-slow.log

-s t 表示按总耗时排序,-t 20 表示只看前 20 条。帝国 CMS 站上出现频率最高的通常是这两类:

  • 列表页:SELECT id,title,newstime FROM phome_ecms_news WHERE classid IN (...) AND checked=1 ORDER BY newstime DESC LIMIT 0,20
  • 搜索页:... FROM phome_ecms_news_index WHERE keyboard LIKE '%关键词%'

第三步:用 EXPLAIN 判断缺哪个索引

这一步要看清 MySQL 到底走了什么索引、扫了多少行。

把慢查询复制到后台「系统 → 执行SQL语句」里,前面加 EXPLAIN 执行:

EXPLAIN SELECT id,title,newstime FROM phome_ecms_news
WHERE classid IN (1,2,3) AND checked=1 ORDER BY newstime DESC LIMIT 20;

重点看三列:

  • type:出现 ALL 就是全表扫描,必须处理;ref、range 算合格。
  • key:显示 NULL 说明没用上任何索引。
  • rows:预估扫描行数,几十万行的表这里如果是六位数,就是它了。
  • Extra:出现 Using filesort 表示排序没走索引。

注意:先确认表引擎。执行 SHOW TABLE STATUS LIKE 'phome_ecms_news';,看 Engine 列。帝国 CMS 7.5 默认建表可能是 MyISAM,索引加法的写法一样,但 MyISAM 拼的是 key_buffer_size,InnoDB 拼的是 innodb_buffer_pool_size,调优参数不同。

第四步:给核心表加联合索引

这一步直接把第三步发现的扫描行数降下来。

以默认前缀 phome_ 为例,执行:

ALTER TABLE phome_ecms_news
ADD INDEX idx_class_checked_time (classid, checked, newstime);

字段顺序不能换:等值条件 classid、checked 在前,排序字段 newstime 在后,这样 MySQL 能同时完成过滤和排序,Using filesort 会消失。

搜索页那张表用前缀索引,别用 LIKE '%词%' 那种全表扫:

ALTER TABLE phome_ecms_news_index ADD INDEX idx_title (title(30));

字段是 text 类型时,创建索引必须带长度,比如 title(30)。

phome_ecms_news_data_1 这张副表存正文,已经有主键 id,不要再给 content 加索引,会撑爆磁盘且毫无收益。

加完索引再跑一次同样的 EXPLAIN,rows 应该从六位数掉到三位数,Extra 里的 Using filesort 应该消失。

注意:索引不是越多越好。每加一个索引,后台发一篇稿就多一次写入开销。全站索引总数控制在每表 5 个以内,加之前先看 SHOW INDEX FROM phome_ecms_news; 里是不是已经有重复字段的索引。

第五步:定期维护,别让索引失效

这一步保证优化效果能长期保持。

在 phpMyAdmin 里选中数据库 → 选中数据表 → 点「结构」标签 → 底部「索引」区可以查看和删除索引,比敲 SQL 直观。

每月执行一次:

ANALYZE TABLE phome_ecms_news;
OPTIMIZE TABLE phome_ecms_news;

ANALYZE 更新统计信息,让优化器选对索引;OPTIMIZE 回收删除数据留下的碎片。表大时 OPTIMIZE 会锁表,安排在凌晨访问低谷做。

另外,帝国 CMS 本身的静态化比任何索引都管用:后台「系统 → 数据更新 → 更新信息页地址」批量生成 HTML,让列表页和内容页直接由 Nginx 返回,数据库压力能下降一个量级。

小结

  • 优化顺序是:开慢查询日志 → mysqldumpslow -s t -t 20 找高频 SQL → EXPLAIN 看 type/key/rows/Extra。
  • 列表页索引写成 (classid, checked, newstime),等值字段在前、排序字段在后。
  • 搜索字段用前缀索引 title(30),text 类型必须带长度。
  • 先 SHOW TABLE STATUS 确认 MyISAM 还是 InnoDB,再决定调哪个缓存参数。
  • 索引不宜多,每表 5 个以内,每月 ANALYZE + OPTIMIZE 一次。
版权声明:本文来自 GJ站长论坛《帝国 CMS 数据库索引优化》
原文链接:https://www.gj0.com/thread-942.html
转载请注明出处并保留本声明;内容仅代表作者观点,与本站立场无关。若本文涉嫌侵权,请联系本站处理。

全部回复 0

还没有回复,来抢沙发~