首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫

千萬級 Discuz 論壇 MySQL CPU 100% 優化實戰:索引缺失、慢查詢、插件副作用全分析

     編輯:MySQL 資料庫相關知識

案例背景

  • Discuz! 5.5.0,cdb_posts 1740 萬筆,總資料 > 2000 萬,DB > 1GB。
  • MySQL CPU 長期 100%,每天重啟多次。
  • 優化後 CPU 降至 10%~20%。

核心排查流程

  1. SHOW PROCESSLIST 觀察高頻 SQL。
  2. SHOW COLUMNS FROM tbl 檢查 WHERE/JOIN/ORDER BY 欄位是否有索引。
  3. ALTER TABLE ... ADD INDEX 補齊缺失索引。
  4. 觀察 CPU 趨勢,迭代直到平穩。

實戰補索引清單(cdb_ 為預設前綴)


ALTER TABLE `cdb_pms` ADD INDEX (`folder`);
ALTER TABLE `cdb_threads` ADD INDEX (`displayorder`);
ALTER TABLE `cdb_threads` ADD INDEX (`dateline`);
ALTER TABLE `cdb_threads` ADD INDEX (`closed`);
ALTER TABLE `cdb_threadsmod` ADD INDEX (`dateline`);
ALTER TABLE `cdb_sessions` ADD INDEX (`invisible`);
ALTER TABLE `cdb_forums` ADD INDEX (`type`);
ALTER TABLE `cdb_forums` ADD INDEX (`displayorder`);

關鍵案例分析

慢 SQL 片段缺失索引影響
WHERE msgfromid=... AND folder='outbox'folder全表掃描 7823 行 × 高頻
WHERE t.displayorder>=0 (common.inc.php)displayorder核心列表查詢,11 萬行全掃
ORDER BY t.dateline DESC (rss.php)datelineFilesort 導致 CPU 飆升
WHERE invisible=0 (forumdisplay.php)invisibleSession 表雖小但高頻

附錄:後續補充案例

首頁四格插件導致 CPU 100%(2007-11-17)


SELECT t.*, f.name FROM cdb_threads t, cdb_forums f
WHERE t.fid<>'S' AND f.fid=t.fid AND f.fid NOT IN (...)
  AND t.closed NOT LIKE 'S' AND t.replies != N
  AND t.displayorder>=N ORDER BY t.views DESC LIMIT N, N

問題:

  • t.closed NOT LIKE 'S':數值欄位用 LIKE,型別轉換導致索引失效。
  • ORDER BY t.views:無索引 Filesort。
  • SELECT t.*:不建議,增加傳輸與緩衝壓力。
  • t.fid <> 'S':數值欄位用字串比較。

解決:關閉插件 → CPU 降至 18%。建議:插件改用定時任務生成靜態快取。

遷移升級遺漏索引問題

許多站點從低版本升級,程式碼更新但資料庫結構未同步補索引,導致千萬級資料量時效能崩塌。

方法論總結

  1. 工具:SHOW PROCESSLIST、slow_query_log、mysqldumpslow、EXPLAIN。
  2. 原則:WHERE/JOIN/ORDER BY/GROUP BY 涉及欄位**必須評估索引**。
  3. 權衡:索引增加寫入開銷,但論壇**讀多寫少**,收益遠大於成本。
  4. 驗證:優化前後對比 CPU、QPS、慢查詢數、鎖等待。
  5. 插件審計:第三方插件 SQL 品質參差不齊,上線前必審 EXPLAIN。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved