彙整自 Percona、MySQL 官方文件、高併發實戰經驗的 21 條核心優化原則,涵蓋查詢緩存、索引設計、SQL 寫法、架構選型、連線管理等維度。每條附帶原理、反模式與最佳實踐。
SELECT * FROM t WHERE date > CURDATE() → 不走緩存。
改用:SET @today = CURDATE(); SELECT * FROM t WHERE date > @today; (變數固定值可命中緩存)。
原則:NOW()、RAND()、UUID()、CONNECTION_ID() 等非確定性函數會導致查詢緩存失效。
關注 type (目標:ref/range/eq_ref,避免 ALL/index)、key (實際用到的索引)、rows (預估掃描行)、Extra (Using index/Using where/Using temporary/Using filesort)。
SELECT 1 FROM users WHERE email = 'a@b.com' LIMIT 1; 找到即停止,避免全表掃描驗證唯一性。
WHERE name LIKE 'abc%' 走索引;WHERE name LIKE '%abc%' **不走索引** (全文索引或應用層搜尋引擎)。
INT JOIN BIGINT、utf8 JOIN utf8mb4、VARCHAR(10) JOIN VARCHAR(20) 皆導致隱式轉換、索引失效。
全表產生隨機數、排序、取前 N。替代方案見 MySQL 隨機查詢優化、高效隨機多筆。
增加網路傳輸、記憶體佔用、緩存污染、覆蓋索引失效。明確列出需要欄位。
業務鍵 (email、身分證) 變更頻率高、長度長、不利叢集索引有序插入。例外:純關聯表 (多對多) 可用複合主鍵。
儲存 1 byte (TINYINT)、比較快、隱含約束。適用:性別、狀態、類別、優先級。PROCEDURE ANALYSE() 會建議轉換。
phpMyAdmin「Propose table structure」即呼叫此函數。建議隨數據量增長而精準,**決策權在人**。
NULL 需額外位圖儲存、比較語義複雜 (三值邏輯)、索引統計偏差。預設 NOT NULL DEFAULT '' 或 0。
防 SQL 注入、解析一次多次執行、二進位協議傳輸高效。MySQL 5.1+ 支援查詢緩存。PHP 使用 mysqli::prepare 或 PDO::prepare。
mysql_unbuffered_query() / MYSQLI_USE_RESULT:逐行讀取、低記憶體、可邊讀邊處理。限制:需讀完或 free_result 才能執行下一查詢,不可 num_rows/data_seek。
INET_ATON('192.168.1.1') / INET_NTOA() / PHP ip2long()/long2ip()。範圍查詢 BETWEEN 極快。
位移計算 O(1)、易緩存、易修復。垂直拆分將變長欄位移出核心表 (見第 16 條)。
例:users (id, name, pwd, role) + user_profiles (id, address, bio, last_login)。避免 last_login 更新導致熱表查詢緩存失效。
避免長鎖表、Replication 延遲、Binlog 膨脹、主從不一致。DELETE FROM big_table WHERE created < '2023-01-01' LIMIT 10000; 迴圈。
TINYINT(1) vs INT、DATE vs DATETIME、CHAR(32) vs VARCHAR(255) (固定長度)。預留擴展空間但勿過度。
InnoDB:行鎖、事務、外鍵、崩潰恢復、叢集索引 → **OLTP 首選**。
MyISAM:表鎖、全文索引 (5.6 前)、COUNT(*) 極快、壓縮表 → **唯讀/分析/日誌** 適用。
Hibernate、Entity Framework、Eloquent、SQLAlchemy。Lazy Loading 方便但易產生大量小查詢,關鍵路徑用 JOIN FETCH/load()/select_related() 預載入。事務批次提交比單條提交快數量級。
PHP mysql_pconnect / PDO::ATTR_PERSISTENT:減少握手但易導致連線洩漏、閒置連線佔用 max_connections、事務狀態殘留。**短連線 + 連線池 (HikariCP、ProxySQL、PHP-FPM 池化) 更可控**。
| # | 檢查項 | 工具/指令 |
|---|---|---|
| 1 | 慢查詢日誌開啟並分析 | pt-query-digest |
| 2 | 核心表主鍵為 BIGINT UNSIGNED AI | SHOW CREATE TABLE |
| 3 | 無 SELECT * 生產代碼 | Code Review / Grep |
| 4 | 無 ORDER BY RAND() | Grep / pt-query-digest |
| 5 | JOIN 欄位類型/字符集一致 | SHOW CREATE TABLE 對比 |
| 6 | InnoDB buffer_pool ≥ 實體記憶體 60% | SHOW VARIABLES |
| 7 | max_connections 足夠且監控使用率 | SHOW STATUS LIKE 'Max_used_connections' |
| 8 | 備份/從庫延遲監控告警 | PMM / 自研 |