首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> MySQL 資料庫 >> MySQL 綜合教學

MySQL EXPLAIN type 連接類型深度解析與實戰示例

     編輯:MySQL 綜合教學

MySQL EXPLAIN type 連接類型深度解析與實戰示例

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,額外處理 NULLWHERE col = 1 OR col IS NULL⭐⭐⭐
index_merge索引合併優化(交集/並集)WHERE key1=1 OR key2=2⭐⭐
unique_subqueryIN 子查詢優化為主鍵查找WHERE id IN (SELECT pk FROM...)⭐⭐⭐
index_subqueryIN 子查詢優化為非唯一索引查找WHERE col IN (SELECT idx_col FROM...)⭐⭐
range索引範圍掃描BETWEEN、>、IN 列表⭐⭐
index全索引掃描覆蓋索引查詢、索引順序排序⭐
ALL全表掃描無索引、範圍過大、統計信息失準⭐

實戰示例(基於 Sakila 數據庫)

1. ALL - 全表掃描

EXPLAIN SELECT COUNT(description) FROM film;
-- type=ALL, rows=1000, Extra=NULL
-- 無 WHERE 條件,無索引可用

2. index - 全索引掃描

EXPLAIN SELECT title FROM film;
-- type=index, key=idx_title, Extra=Using index
-- 覆蓋索引,無需回表

3. range - 索引範圍掃描

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

4. ref - 非唯一索引等值查找

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

5. eq_ref - 唯一索引關聯(JOIN 最優)

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

6. const / system - 常數表優化

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

7. type=NULL - 無需訪問表

EXPLAIN SELECT SYSDATE();
-- type=NULL, Extra=No tables used

優化核心原則

  1. 避免 ALL:為 WHERE/JOIN/ORDER BY/GROUP BY 欄位建立索引
  2. 追求 ref/eq_ref:複合索引前導列區分度高時優先命中
  3. 善用覆蓋索引:Extra=Using index 避免回表,將 index 級提升至 ref 級性能
  4. 警惕 index_merge:通常意味著索引設計不佳,考慮複合索引替代
  5. 範圍查詢優化: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 索引
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved