Discuz 论坛数据量达到百万级时,优化 MySQL 慢查询的核心在于针对高频查询表建立覆盖索引,并对历史数据进行归档处理。操作前需评估业务低峰期,避免创建索引期间锁表影响正常访问。
先说结论:百万级数据下,单纯依靠硬件升级无法解决慢查询,必须结合索引优化与数据归档。
- 先定位:开启慢查询日志,筛选执行时间超过 1 秒的 SQL 语句。
- 先做:对 Discuz 核心表(如 pre_forum_thread)添加联合索引,避免全表扫描。
- 再验证:使用 EXPLAIN 分析执行计划,确认 type 字段不为 ALL。
命令速用版
以下命令用于快速检查慢查询配置及分析日志,需在 MySQL 命令行或客户端执行。
检查慢查询日志状态:
SHOW VARIABLES LIKE 'slow_query_log';
开启慢查询日志(临时生效):
SET GLOBAL slow_query_log = 'ON';
分析慢查询日志工具:
mysqldumpslow -s t -t 10 /var/lib/mysql/slow.log
为什么会这样
数据量增长导致全表扫描成本过高是慢查询的根本原因。Discuz 默认索引主要针对中小规模数据设计,当帖子表(pre_forum_thread)或帖子内容表(pre_forum_post)记录数突破百万行,未加优化的 SELECT 查询会触发磁盘 I/O 瓶颈。MySQL 在执行查询时,如果没有合适索引,需要遍历所有行才能找到匹配数据,随着行数线性增加,查询耗时显著上升。此外,Discuz 部分插件 SQL 写法不规范,如使用 SELECT * 或模糊查询 LIKE '%keyword%',也会加剧索引失效。
分步处理
第一步:开启并收集慢查询日志
修改 MySQL 配置文件(my.cnf 或 my.ini),在 [mysqld] 段添加以下配置,确保记录所有超过 1 秒的查询。
slow_query_log = 1slow_query_log_file = /var/log/mysql/slow.loglong_query_time = 1
修改后重启 MySQL 服务。观察日志文件增长情况,收集至少一个业务高峰期的日志数据。
第二步:分析高频慢 SQL
使用 mysqldumpslow 工具排序找出出现频率最高的慢 SQL。重点关注 Discuz 的帖子列表页、主题查看页对应的查询语句。常见慢查询涉及 pre_forum_thread 表的 tid、fid 字段组合查询。
第三步:添加或优化索引
根据分析结果,在业务低峰期执行 ALTER TABLE 添加索引。例如为帖子表添加版块 ID 与显示顺序的联合索引。
ALTER TABLE pre_forum_thread ADD INDEX idx_fid_displayorder (fid, displayorder);
注意:添加索引期间表可能被锁定,百万级数据可能需要数分钟,务必避开用户活跃时段。
第四步:历史数据归档
对于超过一定年限的帖子数据,移动到历史表或冷存储。Discuz 自带归档功能,可在后台开启“论坛归档”,将旧帖子移入 archiver 表,减少主表数据量。
怎么验证是否生效
执行优化后,再次运行之前的慢查询语句,使用 EXPLAIN 命令查看执行计划。确认 output 中的 type 字段从 ALL 变为 ref 或 range,rows 扫描行数显著减少。同时观察慢查询日志文件,确认相同 SQL 不再频繁出现。页面加载速度需结合浏览器开发者工具 Network 面板综合判断,排除网络延迟干扰。
常见坑
1. 索引过多影响写入:每个索引都会增加 INSERT/UPDATE 的开销,Discuz 发帖频繁,避免在写操作频繁的字段上建立过多索引。
2. 模糊查询失效:LIKE '%keyword%' 会导致索引失效,建议改用全文索引(Fulltext)或接入 Elasticsearch 等搜索引擎。
3. 锁表风险:在线 DDL 操作在旧版本 MySQL 可能锁表,MySQL 5.6+ 支持 online DDL,但仍建议在低峰期操作。
4. 配置未持久化:使用 SET GLOBAL 开启慢查询日志重启后会失效,必须修改配置文件。
常见问题
开启慢查询日志会影响数据库性能吗?
会有轻微影响,但通常可忽略。开启慢查询日志会增加少量磁盘 I/O 开销,在生产环境中建议长期开启,以便持续监控。
Discuz 后台有没有直接的优化开关?
Discuz 后台提供“论坛归档”功能,可减少主表数据量,但无法直接优化 MySQL 索引,索引需通过数据库命令行管理。
数据量多大需要考虑分库分表?
公开资料中没有看到可靠的量化数据。通常单表超过千万级且索引优化无效时,才考虑分库分表,百万级优先优化索引和归档。
参考来源
- MySQL Official Documentation, Slow Query Log, https://dev.mysql.com/doc/refman/8.0/en/slow-query-log.html
- Discuz! Official Website, Forum Archiver Feature, https://www.discuz.net/