承接基礎篇,本文深入解析 MySQL 效能優化四大支柱:索引設計、SQL 改寫、儲存引擎選型、資料型別優化,並附贈大量資料導入、碎片整理、慢查詢定位實戰技巧。
O(log₂N)。O(N),資料量大時災難性。INSERT/UPDATE/DELETE 需同步維護所有索引,I/O 放大。| 適合 | 不適合 |
|---|---|
| 高頻 WHERE/JOIN/ORDER BY 欄位 | 唯一性極低(如性別、狀態碼) |
| 高基數欄位 | 極高頻更新欄位(如登入計數器) |
| 外鍵關聯欄位 | 從不出現在 WHERE 的欄位 |
CREATE INDEX idx_dept_name ON emp(deptno, ename);
deptno(最左列)→ 使用索引。ename → 不使用 複合索引。LIKE 'prefix%' 可用索引,LIKE '%suffix' 不可。OR 條件跨欄位且無全覆蓋索引。LIKE '%...' 開頭萬用字元。SHOW STATUS LIKE 'Handler_read%';
-- Handler_read_key 越高越好(索引命中)
-- Handler_read_rnd_next 越高越差(全表掃描)
| 引擎 | 策略 |
|---|---|
| MyISAM | ALTER TABLE tbl DISABLE KEYS; LOAD/INSERT; ALTER TABLE tbl ENABLE KEYS; |
| InnoDB | 1. 按主鍵排序資料 2. SET unique_checks=0 3. SET autocommit=0 批次提交 |
-- 預設會排序,產生 Using filesort
EXPLAIN SELECT * FROM emp GROUP BY deptno; -- Extra: Using filesort
-- 禁止排序
EXPLAIN SELECT * FROM emp GROUP BY deptno ORDER BY NULL; -- 無 filesort
-- 子查詢需建立臨時表
EXPLAIN SELECT * FROM emp WHERE deptno IN (SELECT deptno FROM dept WHERE loc='NY');
-- JOIN 無臨時表,效能更優
EXPLAIN SELECT e.* FROM emp e JOIN dept d ON e.deptno=d.deptno WHERE d.loc='NY';
若要用索引,OR 兩側欄位都必須有索引,否則全表掃描。考慮 UNION ALL 改寫:
SELECT * FROM t WHERE a=1 OR b=2
-- 改為
SELECT * FROM t WHERE a=1
UNION ALL
SELECT * FROM t WHERE b=2 AND a!=1;
| 引擎 | 特性 | 適用場景 |
|---|---|---|
| MyISAM | 讀快、插入快、表鎖、不支援事務/外鍵、崩潰不安全 | 唯讀/多讀少寫、日誌、報表、暫存表 |
| InnoDB | 行鎖、MVCC、事務 ACID、外鍵、崩潰恢復、叢集索引 | 核心業務、高併發寫入、資料一致性要求高 |
| MEMORY | 資料在記憶體、重啟消失、表鎖、不支援 BLOB/TEXT | 熱點快取、Session、臨時計算、線上狀態 |
FLOAT/DOUBLE 有二進制誤差,金融嚴禁。DATE(3B) < DATETIME(8B) < TIMESTAMP(4B),按需選擇。TINYINT(1B) < SMALLINT(2B) < MEDIUMINT(3B) < INT(4B) < BIGINT(8B)。INET_ATON()/INET_NTOA() 轉換,比 CHAR(15) 省空間、利索引。-- 頻繁 DELETE/UPDATE 產生碎片
OPTIMIZE TABLE tbl_name;
-- 效果:釋放空間、重排資料、重建索引
InnoDB 共享表空間 (ibdata1) 不支援 OPTIMIZE TABLE,需 ALTER TABLE tbl ENGINE=InnoDB 重建(會鎖表,大表用線上工具)。
SET long_query_time=1;(預設 10s 太寬鬆)slow_query_log=1, slow_query_log_file=/var/log/mysql/slow.logpt-query-digest, mysqldumpslowEXPLAIN 分析執行計畫,針對 type=ALL, Using filesort, Using temporary 優化。效能優化無銀彈,唯有「測量 → 定位 → 優化 → 驗證 → 迭代」的科學循環。建立「索引變更審核機制」、「慢查詢週報」、「核心 SQL 基準測試」,讓優化成為持續工程實踐而非一次性救火。