表示 MySQL 在表中查找行的訪問策略,按性能從差到好排序:
ALL → index → range → ref → eq_ref → const/system → NULL
EXPLAIN SELECT * FROM a;
-- type: ALL
-- 掃描全表,無索引可用
加 LIMIT 100 仍為 ALL,只是掃描 100 行後停止。
CREATE TABLE a(a_id INT NOT NULL, KEY(a_id));
INSERT INTO a VALUES(1),(2);
EXPLAIN SELECT * FROM a;
-- type: index
-- 按索引順序讀取,避免排序,但仍讀全表
CREATE TABLE a(a_id INT NOT NULL, KEY(a_id));
INSERT INTO a VALUES(1),(2),(3),(4),(5),(6),(7),(8),(9),(10);
EXPLAIN SELECT * FROM a WHERE a_id > 1;
-- type: range
-- key_len 顯示用到的索引長度
IN (1,3,4)、BETWEEN、>= 等均觸發 range。
EXPLAIN SELECT * FROM a WHERE a_id = 1;
-- type: ref
-- 可能返回多行
CREATE TABLE a(id INT PRIMARY KEY);
CREATE TABLE a_info(id INT PRIMARY KEY, title CHAR(1));
INSERT INTO a VALUES(1),(2);
INSERT INTO a_info VALUES(1,'a'),(2,'b');
EXPLAIN SELECT * FROM a JOIN a_info USING(id);
-- a_info type: eq_ref
-- 每行最多匹配一行,連接極快
若 a_info.id 為普通索引 → 變為 ref;無索引 → ALL。
CREATE TABLE a(id INT PRIMARY KEY, c1 CHAR(20), c2 TEXT, c3 TEXT);
INSERT INTO a VALUES(1,'asdfasdf','asdfasdf','asdfasdf');
EXPLAIN EXTENDED SELECT * FROM a WHERE id=1;
-- type: const
SHOW WARNINGS;
-- Message: select '1' AS `id`,'asdfasdf' AS `c1`,'asdfasdf' AS `c2`,'asdfasdf' AS `c3` from `test`.`a` where 1
-- 數據已內聯,無需運行時讀表
若 WHERE id IN (1,2) 返回 >1 行 → 降級為 range。
EXPLAIN SELECT 1 FROM a WHERE 1=0;
-- type: NULL
-- 優化器判定無滿足行,直接返回空集
| 當前類型 | 目標類型 | 手段 |
|---|---|---|
| ALL | range/ref | 添加 WHERE 條件列索引 |
| index | range/ref | WHERE 加索引列條件、避免 SELECT * |
| range | ref/eq_ref | 將範圍條件改為等值、建立唯一索引 |
| ref | eq_ref | 將非唯一索引改為主鍵/唯一索引 |
| ref/eq_ref | const | 確保 WHERE 條件命中唯一鍵且只返回 1 行 |
EXPLAIN SELECT ... 觀察 type;possible_keys、key、key_len、rows(預估掃描行數);rows × 併發 QPS < CPU 核心數 × 1000 為健康線;