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

MySQL EXPLAIN 執行計劃深度解析:SQL 優化利器的輸出格式、字段含義與實戰優化策略

     編輯:MySQL 綜合教學

EXPLAIN 核心價值

EXPLAIN 輸出 MySQL 優化器對 SQL 的**執行計劃**:掃描順序、索引選擇、連接算法、預估掃描行數。是**慢查詢優化、索引設計驗證、執行路徑預判**的核心工具。

輸出字段完整解析 (MySQL 5.7/8.0)

字段含義優化關注點
idSELECT 識別符,遞增;UNION 結果為 NULL多 SELECT 執行順序
select_type查詢類型:SIMPLE、PRIMARY、SUBQUERY、DERIVED、UNION、DEPENDENT SUBQUERY 等子查詢優化目標:轉 JOIN、物化、半連接
table訪問的表名 / <derivedN> / <unionM,N>關聯順序驗證
partitions匹配的分區 (分區表)分區裁剪驗證
type (關鍵)訪問類型/連接類型,效能由好到壞:
system > const > eq_ref > ref > fulltext > ref_or_null > index_merge > unique_subquery > index_subquery > range > index > ALL
核心指標:至少達到 ref,避免 ALL/index
possible_keys可能用到的索引為 NULL 表示無索引可用,需建索引
key實際使用的索引與 possible_keys 差異分析;可用 FORCE INDEX 指定
key_len使用的索引長度 (字節)推斷聯合索引使用了幾列 (最左前綴)
ref與 key 配合的比較值:const、列名、函數驗證關聯條件正確性
rows (關鍵)預估掃描行數越小越好;與實際行數對比驗證統計信息準確性
filtered按表條件過濾後剩餘行百分比 (EXPLAIN EXTENDED)低百分比提示條件過濾性差
Extra (關鍵)額外信息:
Using index (覆蓋索引)、Using where (Server 層過濾)、Using temporary (臨時表)、Using filesort (外部排序)、Using join buffer (Block Nested Loop)、FirstMatch/LooseScan (半連接優化)
重點優化目標:消除 filesort/temporary、爭取 Using index

type 字段效能階梯深度解讀

第一梯隊:極速 (系統表/常數查找)

  • system:表僅 1 行 (系統表)
  • const:主鍵/唯一索引與常數比較,最多 1 行,查詢優化階段常數折疊

第二梯隊:高效索引查找

  • eq_ref:多表 JOIN 最優,關聯列為主鍵/唯一索引,**每次關聯精確匹配 1 行**
  • ref:非唯一索引關聯,**匹配多行**,但行數可控時可接受

第三梯隊:索引合併/範圍掃描

  • index_merge:多索引 OR 合併,intersect/union/sort_union 三種策略
  • range:索引範圍掃描 (>, <, BETWEEN, IN, LIKE 'prefix%')

第四梯隊:需優化 (全掃描)

  • index:全索引樹掃描。
    Case 1:Using index (覆蓋索引,僅掃描索引葉節點) — 可接受
    Case 2:無 Using index (全索引掃描後回表/過濾) — **需優化**
  • ALL:全表掃描 (最差),必須建索引或改寫 SQL

實戰優化策略:從 EXPLAIN 到索引設計

策略一:消除 Using filesort / Using temporary


-- 原 SQL:臨時表 + 排序
SELECT * FROM orders WHERE status = 1 ORDER BY create_time DESC LIMIT 20;
-- EXPLAIN: Using where; Using temporary; Using filesort

-- 優化:建立覆蓋索引,順序匹配 WHERE + ORDER BY
ALTER TABLE orders ADD INDEX idx_status_ctime_id (status, create_time DESC, id DESC);
-- EXPLAIN: Using index condition;  -- 無 temporary/filesort,直接索引下推返回

策略二:聯合索引最左前綴與 key_len 推斷


INDEX idx_a_b_c (a, b, c)  -- a:4字節, b:4字節, c:4字節 (INT)
-- SQL: WHERE a=1 AND b=2 → key_len=8 (使用 a,b)
-- SQL: WHERE a=1 → key_len=4 (僅使用 a)
-- SQL: WHERE b=2 → key_len=NULL (無法使用,非最左)

策略三:關聯查詢驅動表選擇與 join buffer

  • MySQL 採用 **Nested Loop Join**,優化器選擇 rows 最小的表作為驅動表 (外層循環)
  • Using join buffer (Block Nested Loop):被驅動表無索引,需優化關聯列索引
  • 小表驅動大表,被驅動表關聯列**必須有索引**

策略四:EXPLAIN EXTENDED + SHOW WARNINGS 觀察優化器重寫


EXPLAIN EXTENDED SELECT * FROM t WHERE a > 10;
SHOW WARNINGS;
-- 可見優化器內部重寫後的 SQL、條件下推、常數傳播等優化動作

避坑指南與進階技巧

  1. EXPLAIN 不執行 SQL:僅優化階段,無鎖、無副作用,生產可直接跑
  2. 統計信息不準導致誤判:ANALYZE TABLE t 更新統計,或 innodb_stats_persistent=ON 持久化
  3. 子查詢優化:DEPENDENT SUBQUERY → 改寫為 JOIN 或 EXISTS,啟用 optimizer_switch='semijoin=on'
  4. 8.0 新特性:EXPLAIN ANALYZE 實際執行並顯示真實耗時/行數、**可視化樹狀輸出** (EXPLAIN FORMAT=TREE)

總結: 讀懂 EXPLAIN 是 DBA/開發進階的分水嶺。**重點盯三字段:type (訪問類型)、rows (掃描行數)、Extra (額外開銷)**。目標:type 至少 ref、rows 最小化、Extra 無 filesort/temporary、爭取 Using index。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved