Discuz 高并发下数据库查询慢,优先通过开启 MySQL 慢查询日志定位具体 SQL,再针对高频 WHERE 条件和 JOIN 字段补充索引。适用场景为读多写少的论坛浏览场景,风险边界在于创建索引期间可能锁表,需在业务低峰期操作。
先说结论:盲目添加索引无法解决所有慢查询,必须先通过慢查询日志锁定具体语句,再结合执行计划分析。
先定位:开启 MySQL 慢查询日志,捕获执行时间超过阈值的 SQL 语句。
先做:使用 EXPLAIN 分析查询计划,针对区分度高的字段创建索引。
再验证:观察慢查询日志减少情况,确认索引命中且写入性能未明显下降。
命令速用版
以下命令用于快速检查慢查询状态和分析 SQL 执行计划,需在 MySQL 命令行或管理工具中执行。
# 查看慢查询日志是否开启
SHOW VARIABLES LIKE 'slow_query_log';
# 查看慢查询阈值(单位秒)
SHOW VARIABLES LIKE 'long_query_time';
# 分析具体 SQL 的执行计划
EXPLAIN SELECT * FROM pre_forum_thread WHERE tid = 12345;
# 添加索引(示例:为 thread 表的 fid 字段加索引)
ALTER TABLE pre_forum_thread ADD INDEX idx_fid (fid);
为什么会这样
数据库查询慢的根本原因通常是全表扫描,索引能显著减少需要扫描的数据行数。Discuz 默认表结构针对通用场景设计,高并发下特定板块或热门帖子的查询频率远超平均水平,导致默认索引不足以覆盖热点查询路径。当 SQL 语句的 WHERE 条件或 JOIN 字段缺乏索引时,MySQL 需要遍历整张表查找数据,随着数据量增长,耗时线性增加。
分步处理
按以下步骤操作,每一步完成后确认无误再进行下一步,避免直接生产环境变更。
1. 开启慢查询日志
修改 MySQL 配置文件(my.cnf 或 my.ini),在 [mysqld] 段添加或修改以下配置,设置阈值为 1 秒或更低。