Windows 2003 + IIS + PHP + MySQL,mysqld-nt.exe CPU 持續 100%。停用某站點(日 IP 2000,PV 3萬)即降下,啟用即升高。該站 DB 39 表、60 萬筆、45 MB,理論不應佔滿 CPU。
# 導出當前配置
mysqld.exe --help > output.txt
# 發現 tmp_table_size=32M (預設)
# 修改 my.ini
[mysqld]
tmp_table_size=200M
# 重啟服務
效果:CPU 從 100% 直線 → 97%~100% 震盪,有改善但未解決。
mysql> SHOW PROCESSLIST;
# 反覆執行,發現兩條高頻 SQL
SELECT t1.pid, t2.userid, t3.count, t1.date
FROM _mydata AS t1
LEFT JOIN _myuser AS t3 ON t1.userid = t3.userid
LEFT JOIN _mydata_body AS t2 ON t1.pid = t3.pid
ORDER BY t1.pid LIMIT 0,15
_mydata 只有 PK (pid),userid 無索引,JOIN 時全表掃描。
→ ALTER TABLE `_mydata` ADD INDEX (`userid`);
CPU 降至 80%。
SELECT COUNT(*) FROM _mydata AS t1, _mydata_key AS t2
WHERE t1.pid = t2.pid AND t2.keywords = '孔雀'
_mydata_key 33 萬行,keywords 無索引,全表掃描字串比對。
→ ALTER TABLE `_mydata_key` ADD INDEX (`keywords`);
CPU 降至 50%~70%。
同機器跑多個 Discuz,套用前文 8 條補索引,CPU 進一步降至正常區間。
The table ... is full 錯誤與大量磁碟 I/O。GROUP BY、ORDER BY、UNION、DISTINCT 產生臨時表時需調大。Created_tmp_disk_tables / Created_tmp_tables 比例,磁碟臨時表佔比高時調大。必建索引場景:
WHERE col = ...JOIN ON t1.col = t2.colORDER BY col / GROUP BY colMAX(col) / MIN(col)原理:B-Tree 索引將 O(N) 全掃降為 O(log N) 定位。1000 行表快 100 倍,百萬行快 10 萬倍。
多欄索引策略:INDEX (col1, col2) 可服務 WHERE col1=... AND col2=...;單欄索引由優化器選擇選擇性最高者。
EXPLAIN 驗證)。SHOW PROCESSLIST 與慢查詢日誌。ANALYZE TABLE 更新統計資訊,防止優化器誤判。SELECT *、隱式型別轉換、LIKE '%keyword%' 導致索引失效。