面對緩慢的 SQL,EXPLAIN(或 DESC)是首選診斷工具。以下以雙表關聯聚合查詢為例:
EXPLAIN SELECT SUM(profit)
FROM sales a, company b
WHERE a.company_id = b.id AND a.year = 2006\G
| 欄位 | 核心含義 | 性能關鍵點 |
|---|---|---|
| id | 查詢序號 | 相同 id 表示同一查詢塊,按順序執行 |
| select_type | 查詢類型 | SIMPLE(無子查詢/關聯)、PRIMARY(外層)、UNION、SUBQUERY 等 |
| table | 輸出結果表 | 關注驅動表與被驅動表順序 |
| type | 連接/訪問類型 | system > const > eq_ref > ref > range > index > ALL(由優到劣) |
| possible_keys | 可能用到的索引 | 為空提示無可用索引 |
| key | 實際使用索引 | 為空 = 全表掃描,需優先優化 |
| key_len | 索引長度(字節) | 推斷聯合索引用了幾列 |
| ref | 關聯比較列/常量 | const 表示常量等值查詢 |
| rows | 預估掃描行數 | 越小越好,結合 type 判斷效率 |
| Extra | 額外信息 | Using index(覆蓋索引)、Using where、Using temporary、Using filesort 需警惕 |
*************************** 1. row ***************************
table: a
type: ALL
possible_keys: NULL
key: NULL
rows: 12
Extra: Using where
*************************** 2. row ***************************
table: b
type: ALL
possible_keys: NULL
key: NULL
rows: 12
Extra: Using where
診斷: 表 sales(別名 a)在 year 列無索引,導致全表掃描 12 行(實際大表中行數可達百萬級)。
CREATE INDEX idx_sales_year ON sales(year);
*************************** 1. row ***************************
table: a
type: ref
possible_keys: idx_sales_year
key: idx_sales_year
key_len: 4
ref: const
rows: 3
Extra:
*************************** 2. row ***************************
table: b
type: ALL
possible_keys: NULL
key: NULL
rows: 12
Extra: Using where
效果: 表 a 掃描行數從 12 降至 3,若表有 1000 萬行且年份選擇性高,性能提升可達數量級。
Extra 出現 Using index 表示無需回表,極大提升速度。(a,b,c) 支持 a、a,b、a,b,c 查詢,不支持單獨 b 或 c。EXPLAIN ANALYZE SELECT ...
輸出實際執行時間、實際掃描行數、循環次數,對比預估值精準定位優化器誤判場景。