MySQL 優化入門必掌握:EXPLAIN、SHOW VARIABLES、SHOW STATUS、SHOW PROCESSLIST。大表禁用 GROUP BY(臨時表+文件排序風險極大)。索引設計遵循「少而精」原則。
>, >=, =, <, <=, IS NULL, BETWEEN, IN(), LIKE 'prefix%'
LIKE '%suffix'、LIKE '%middle%' 導致索引失效WHERE varchar_col = 123(數字比較字符串)WHERE YEAR(date_col) = 2023、WHERE col1 + 1 = 10| 列 | 含義 | 關鍵判讀 |
|---|---|---|
| id | 查詢序號 | 相同 id 從上往下執行;不同 id 值大優先 |
| select_type | 查詢類型 | SIMPLE(無子查詢/UNION)、PRIMARY(最外層)、SUBQUERY、DERIVED(派生表/子查詢 FROM)、UNION、UNION RESULT |
| table | 訪問的表 | 別名或 |
| partitions | 匹配的分區 | 分區表才顯示 |
| type | 訪問類型(核心!) | 從優到劣:system > const > eq_ref > ref > range > index > ALL |
| possible_keys | 理論可用索引 | 為空 → 無索引可用,需檢查 WHERE/JOIN 條件列 |
| key | 實際使用索引 | NULL → 全表掃描!可用 FORCE/USE/IGNORE INDEX 干預 |
| key_len | 索引鍵長度 | 越短越好(不損失精度前提下),推斷聯合索引用了幾列 |
| ref | 索引對比的列/常量 | const、func、NULL、列名 |
| rows | 預估掃描行數 | 越小越好,結合 type 判斷效率 |
| filtered | 按條件過濾後剩餘比例% | 越接近 100 越好 |
| Extra | 額外信息(核心!) | 見下表 |
>, <, >=, <=, BETWEEN, IN, LIKE 'prefix%')| 值 | 含義 | 嚴重程度 | 對策 |
|---|---|---|---|
| Using filesort | 需額外排序操作(無索引支持 ORDER BY/GROUP BY) | 🔴 嚴重 | 加索引匹配排序列、避免跨表排序 |
| Using temporary | 需建立臨時表(GROUP BY/DISTINCT/ORDER BY 列不一致) | 🔴 嚴重 | 優化索引、避免 SELECT *、調大 tmp_table_size |
| Using index | 覆蓋索引:僅訪問索引樹,無需回表 | 🟢 極佳 | 設計覆蓋索引,SELECT 列 ⊆ 索引列 |
| Using where | Server 層過濾(存儲引擎返回後再篩選) | 🟡 正常/警示 | 若 type=ALL/index 且無 Using index,說明全表掃描後過濾 |
| Using index condition | ICP (Index Condition Pushdown):存儲引擎層過濾 | 🟢 優秀 | MySQL 5.6+ 自動啟用,需索引包含 WHERE 列 |
| Range checked for each record | 無理想索引,逐行嘗試決定用哪個索引 | 🔴 極差 | 重設計索引 |
| Distinct / Not exists | 優化後提前終止掃描 | 🟢 正常 | — |
-- 原查詢
SELECT id, name FROM users WHERE status=1 AND create_time > '2023-01-01';
-- EXPLAIN: type=ref, key=idx_status, rows=50000, Extra=Using where
-- 優化:建立覆蓋索引
ALTER TABLE users ADD INDEX idx_status_ct_name (status, create_time, name);
-- EXPLAIN: type=range, key=idx_status_ct_name, rows=200, Extra=Using index
-- 原查詢
SELECT * FROM orders WHERE user_id=100 ORDER BY created_at DESC LIMIT 10;
-- EXPLAIN: type=ref, key=idx_user_id, rows=5000, Extra=Using where; Using filesort
-- 優化:聯合索引匹配 WHERE + ORDER BY
ALTER TABLE orders ADD INDEX idx_uid_created (user_id, created_at DESC);
-- EXPLAIN: type=ref, key=idx_uid_created, rows=10, Extra=Using index
SELECT * FROM t1 FORCE INDEX (idx_a) WHERE a=1 AND b=2;
-- 僅在確信優化器選錯(如統計信息過期)時使用,慎用 IGNORE INDEX
SHOW FULL PROCESSLIST;
-- 關鍵列:
-- Id, User, Host, db, Command, Time, State, Info
-- 關注:Time 長、State='Sending data'/'Copying to tmp table'/'Locked'、Info 為慢查詢 SQL
SHOW ENGINE INNODB STATUS 死鎖分析MySQL 優化無銀彈,但 EXPLAIN 是唯一通用的「X 光機」。讀懂執行計劃,理解存儲引擎行為,優化就有了確定性方向。