系統整理 19 項 MySQL 效能優化核心原則,涵蓋 SQL 改寫、索引設計、架構配置、監控排查,附帶實測對比與避坑指南。
原理:相同 SELECT 結果快取在記憶體,後續直接返回。
-- 失效場景:非確定性函數
SELECT * FROM user WHERE signup_date >= CURDATE(); -- 不快取
-- 優化:應用層計算日期
$today = date('Y-m-d');
SELECT * FROM user WHERE signup_date >= '$today'; -- 可快取
現狀:MySQL 5.7 棄用,8.0 移除。建議用 Redis/應用層快取替代。
EXPLAIN SELECT u.username, g.group_name
FROM users u JOIN groups g ON u.group_id = g.id;
-- 關注:type=ref/eq_ref、key=idx_group_id、rows=預估掃描行
關鍵欄位:`type` (系統→const→eq_ref→ref→range→index→ALL)、`key` (實際用索引)、`rows` (預估掃描)、`Extra` (Using index/where/filesort/temporary)。
-- 低效
SELECT * FROM user WHERE country = 'China';
-- 高效 (找到 1 筆即停止)
SELECT 1 FROM user WHERE country = 'China' LIMIT 1;
WHERE、JOIN、ORDER BY、GROUP BY 涉及欄位評估建索引。避免過度索引 (寫入放大)。
-- 極慢:全表掃描 + 臨時表 + 檔案排序
SELECT * FROM table ORDER BY RAND() LIMIT 10;
-- 優化:應用層隨機 ID 或兩步查詢
SELECT MAX(id) FROM table; -- 應用層隨機生成 ID
SELECT * FROM table WHERE id >= $rand_id LIMIT 10;
儲存為 TINYINT,壓縮空間、比較快。適用:性別、狀態、類型、部門等固定枚舉。
SELECT * FROM table PROCEDURE ANALYSE();
-- 建議:INT→MEDIUMINT、VARCHAR→ENUM 等 (需有實際資料才準確)
-- 存入
INSERT INTO ip_log (ip) VALUES (INET_ATON('192.168.1.1'));
-- 查詢範圍
SELECT * FROM ip_log WHERE ip BETWEEN INET_ATON('192.168.1.0') AND INET_ATON('192.168.1.255');
-- 顯示
SELECT INET_NTOA(ip) FROM ip_log;
-- 避免長鎖表阻塞
WHILE 1 DO
DELETE FROM logs WHERE log_date <= '2009-11-01' LIMIT 1000;
IF ROW_COUNT() = 0 THEN LEAVE; END IF;
DO SLEEP(0.05); -- 釋放鎖讓其他查詢進入
END WHILE;
| 場景 | 引擎 | 理由 |
|---|---|---|
| 高併發 OLTP、需事務 | InnoDB | 行鎖、MVCC、崩潰恢復 |
| 唯讀/日誌/全文搜尋(舊版) | MyISAM | 表鎖、壓縮、全文索引 |
| 暫存/中間表 | MEMORY | 記憶體級速度 |
PHP `mysql_pconnect()`、Java 連線池預設持久。問題:連線洩漏、佔用 max_connections、閒置連線被防火牆斷開。建議:短連線 + 連線池,配合 `validationQuery`。
-- 慢 (18.87s):依賴子查詢執行計畫差
SELECT * FROM guang_deal_outs
WHERE deal_id IN (SELECT id FROM guang_deals WHERE id = 100017151);
-- 快 (0.01s):JOIN 使優化器選擇最佳路徑
SELECT a.* FROM guang_deal_outs a
INNER JOIN guang_deals b ON a.deal_id = b.id
WHERE b.id = 100017151;
-- EXPLAIN 對比關鍵差異:
-- 子查詢: select_type=DEPENDENT SUBQUERY, type=ALL (全表掃描外表)
-- JOIN: select_type=SIMPLE, type=const/ref (索引查找)
| 優先級 | 動作 | 投入產出比 |
|---|---|---|
| P0 | 慢查詢 SQL 改寫 + 索引補齊 | 極高 (分鐘級見效) |
| P1 | 架構調整 (分表/分區/讀寫分離/快取層) | 高 (需開發配合) |
| P2 | 參數調優 (Buffer Pool、連線池、日誌同步) | 中 (需壓測驗證) |
| P3 | 硬體升級 (SSD、記憶體、CPU) | 低 (成本高、非根治) |