EXPLAIN 輸出中的 type 列揭示了 MySQL 訪問表數據的方式,是 SQL 優化的核心指標。本文系統梳理 12 種訪問類型的性能梯度,並基於 Sakila 標準樣本庫給出真實執行計劃示例。
| 類型 | 含義 | 典型場景 | 性能評級 |
|---|---|---|---|
system | 表僅有一行(系統表) | 常數表優化 | ⭐⭐⭐⭐⭐ |
const | 主鍵/唯一索引等值查詢,最多一行匹配 | WHERE id = 1 | ⭐⭐⭐⭐⭐ |
eq_ref | 唯一索引掃描,JOIN 時每行匹配一行 | 主鍵關聯 ON a.id = b.id | ⭐⭐⭐⭐ |
ref | 非唯一索引等值查詢,匹配少量行 | WHERE status = 1、外鍵關聯 | ⭐⭐⭐ |
ref_or_null | 類似 ref,額外處理 NULL | WHERE col = 1 OR col IS NULL | ⭐⭐⭐ |
index_merge | 索引合併優化(交集/並集) | WHERE key1=1 OR key2=2 | ⭐⭐ |
unique_subquery | IN 子查詢優化為主鍵查找 | WHERE id IN (SELECT pk FROM...) | ⭐⭐⭐ |
index_subquery | IN 子查詢優化為非唯一索引查找 | WHERE col IN (SELECT idx_col FROM...) | ⭐⭐ |
range | 索引範圍掃描 | BETWEEN、>、IN 列表 | ⭐⭐ |
index | 全索引掃描 | 覆蓋索引查詢、索引順序排序 | ⭐ |
ALL | 全表掃描 | 無索引、範圍過大、統計信息失準 | ⭐ |
EXPLAIN SELECT COUNT(description) FROM film; -- type=ALL, rows=1000, Extra=NULL -- 無 WHERE 條件,無索引可用
EXPLAIN SELECT title FROM film; -- type=index, key=idx_title, Extra=Using index -- 覆蓋索引,無需回表
EXPLAIN SELECT * FROM payment WHERE customer_id > 300 AND customer_id < 400; -- type=range, key=idx_fk_customer_id, rows=2637, Extra=Using where EXPLAIN SELECT * FROM payment WHERE customer_id IN (200,300,400); -- type=range, key=idx_fk_customer_id, Extra=Using index condition
EXPLAIN SELECT * FROM payment WHERE customer_id = 305; -- type=ref, key=idx_fk_customer_id, ref=const, rows=25 -- 複合索引前導列查詢 CREATE INDEX idx_first_last ON customer(first_name, last_name); EXPLAIN SELECT first_name FROM customer WHERE first_name = 'JESSIE'; -- type=ref, key=idx_first_last, Extra=Using where; Using index
EXPLAIN SELECT * FROM film a JOIN film_text b ON a.film_id = b.film_id; -- a 表 type=eq_ref, key=PRIMARY, ref=sakila.b.film_id, rows=1
CREATE TABLE t1(id INT, ename VARCHAR(20) UNIQUE); INSERT INTO t1 VALUES(1,'robin'),(2,'jack'),(3,'henry'); EXPLAIN SELECT * FROM (SELECT * FROM t1 WHERE ename='robin') x; -- 衍生表 x: type=system (僅 1 行) -- t1: type=const, key=ename
EXPLAIN SELECT SYSDATE(); -- type=NULL, Extra=No tables used
Extra=Using index 避免回表,將 index 級提升至 ref 級性能IN 列表過大時優化器可能退化為 ALL,考慮臨時表或 JOIN 重寫Using index condition(ICP,Index Condition Pushdown):5.6+ 新特性,在存儲引擎層過濾,減少回表Using where; Using index:索引覆蓋但仍需 WHERE 過濾Using filesort:出現時需優化 ORDER BY 索引Using temporary:出現時需優化 GROUP BY/DISTINCT 索引