MySQL--解讀執行計劃

作爲一名業務系統的開發人員,在企業日常開發工作中,天天相伴最多的是java代碼和Sql語句。Sql的執行計劃能很好的幫忙開發人員定位SQL的性能問題,預防慢SQL影響生產服務器。每個數據庫的執行計劃查看和呈現都不太一樣,然而MySql應該說是當下流行的數據庫,需要了解一下。

調用執行計劃


EXPLAN 關鍵字:EXPLAN SELECT * FROM TABLE …

EXPLAIN SELECT
	u.*, r.*
FROM
	t_user u
LEFT JOIN t_role_user ru ON u.user_no = ru.user_no
LEFT JOIN t_role_resource rr ON ru.role_id = rr.role_id
LEFT JOIN t_resource r ON rr.resouce_id = r.id
WHERE
	u.USER_NO = '88888888';

執行計劃結果
在這裏插入圖片描述

執行計劃字段


在這裏插入圖片描述

id


含義:包含一組數字,表示查詢中執行select子句或操作表的順序

  • id相同:可以認爲是一組,執行順序由上至下。
  • id不同:如果是子查詢,id的序號會遞增,id值越大優先級越高,越先被執行
  • id爲null時表示一個結果集,不需要使用它查詢,常出現在包含union等查詢語句中
    在這裏插入圖片描述

select_type


含義:表示查詢中每個select子句的類型(簡單 OR複雜)

常見類型:

  • SIMPLE:查詢中不包含任何子查詢或union等查詢
  • PRIMARY:查詢中若包含任何複雜的子部分,最外層查詢則爲PRIMARY
  • SUBQUERY:在SELECT或WHERE列表中包含了子查詢
  • DEPENDENT SUBQUERY:相關子查詢,子查詢的查詢方式依賴於外面的查詢結果
    • mysql子查詢很糟糕,不會將子查詢結果集給到外層,而是外層結果先查出來,然後逐條執行匹配子查詢
  • DERIVED:在FROM列表中包含的子查詢
  • UNION:出現在union後的查詢語句中
  • UNION RESULT:從UNION表獲取結果集

table


含義:表示這條查詢語句所查詢的數據表或結果集。

  • 查詢使用了別名,那麼這裏顯示的是別名
  • 不涉及對數據表的操作,那麼這顯示爲null
  • 顯示爲< derivedN >就表示這個是臨時表,後邊的N就是執行計劃中的id,表示結果來自該id查詢結果。
  • 如果是尖括號括起來的<unionM,N>,也是一個臨時表,表示這個結果來自於union查詢的id爲M,N的結果集。

解讀select_type和table

例子

EXPLAIN
select *,(select 1 from t_role) as 'role',
 (select name from t_user where user_no = ru.user_no) as 'name'   
from 
 (select * from t_role_user) ru 
UNION
select *,'role','name' from t_role_user;

在這裏插入圖片描述

解析執行計劃

  • 第一行:第一個select ,id爲1則執行順序爲倒數,PRIMARY該查詢爲外層查詢,table列爲derived4,表示查詢的結果集來自一個衍生表,其中4表示id爲4的select
  • 第二行:id 爲4,是第二個執行的select(5->4),DERIVED說明from中包含子查詢,table爲t_role_user表示的查詢結果集爲t_role_user表。所以就是:(select * from t_role_user) ru 子查詢
  • 第三行:DEPENDENT SUBQUERY,table 是t_user 顯然語句是,(select name from t_user where user_no = ru.user_no) as ‘name’ 這個語句的結果集依賴於外層表ru的結果集,user_no依賴ru.user_no的結果集。
  • 第四行:SUBQUERY 這邊是select中有子查詢,table是t_role,語句是(select 1 from t_role) as ‘role’ ,因爲他不依賴外層結果集,所以是SUBQUERY
  • 第五行:UNION 關鍵字後面的一個select ,這邊就是 select *,‘role’,‘name’ from t_role_user
  • 第六行:id爲null union 結果集。table爲<union1,5> 說明是id1和id5的select結果集進行union。

額外的DEPENDENT SUBQUERY

上面第三行的DEPENDENT SUBQUERY,本來就是根據外層結果集作爲裏層條件查詢的,性能在預料之內。但在下面這種情況的DEPENDENT SUBQUERY卻是意向不到的,比如:

EXPLAIN
select * from t_role_user 
where role_id  in (select id from t_role );

在這裏插入圖片描述
這種情況,2依賴於外層1的結果集;並非想象中,先執行select id from t_role 的結果集,再交給role_id in來查詢。而是先查詢select * from t_role_user 的大結果集,再逐條匹配子結果集(該問題在5.6版本之後就優化了)。

type


含義:訪問類型;表示MySQL在表中找到所需行的方式

常見類型:

在這裏插入圖片描述

性能:左–>右,差–>好

  • ALL:Full Table Scan, MySQL將遍歷全表以找到匹配的行;全表掃描
EXPLAIN select * from t_user where name = '';

在這裏插入圖片描述

  • index:Full Index Scan,index與ALL區別是index遍歷索引樹。
EXPLAIN select id from t_user;

在這裏插入圖片描述

  • range:索引範圍掃描,對索引的掃描開始於某一點,返回匹配值域的行;常見於between,< >等的查詢
// 根據不同的情況,同樣類型的range,性能會有差異
EXPLAIN select * from t_user where id between 0 and 80;
EXPLAIN select * from t_user where id >=0 and age <= 80;
EXPLAIN select * from t_user where id in (0,30,50);

在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述

  • ref:非唯一性索引掃描,返回匹配某個單獨值的所有行。
EXPLAIN select * from t_user where age = 3;

在這裏插入圖片描述

  • eq_ref:唯一性索引掃描,對於每個索引鍵,表中只有一條記錄與之匹配。常見於主鍵或唯一索引掃描。
EXPLAIN select * from t_role r join t_role_user ru on r.id = ru.id;

在這裏插入圖片描述

  • const / system:使用主鍵或者唯一索引,且匹配的結果只有一條記錄,常出現於where條件是=的情況。system是const類型的特例,查詢的表本身只有一行。
EXPLAIN select * from (select * from t_role where id = 1) as rs;

在這裏插入圖片描述

  • NULL:MySQL在優化過程中分解語句,執行時甚至不用訪問表或索引。
EXPLAIN select min(id) from t_role;

在這裏插入圖片描述

possible_keys


含義:可能使用的索引

  • 可能使用的索引,注意不一定會使用。
  • 查詢涉及到的字段上若存在索引,則該索引將被列出來。
  • 當該列爲NULL時就要考慮當前的SQL是否需要優化了。

key


含義:實際使用的索引

  • 顯示MySQL在查詢中實際使用的索引,若沒有使用索引,顯示爲NULL。
  • 查詢中若使用了覆蓋索引(覆蓋索引:索引的數據覆蓋了需要查詢的所有數據),則該索引僅出現在key列表中,而possible_keys爲NULL
EXPLAIN select user_no from t_user ;

在這裏插入圖片描述

  • select_type爲index_merge時,這裏可能出現兩個以上的索引,其他的select_type這裏只會出現一個。

key_len


含義:表示索引中使用的字節數,可通過該列計算查詢中使用的索引的長度

ref


含義:表示表的連接匹配條件,即哪些列或常量被用於查找索引列上的值

  • 如果是使用的常數等值查詢,這裏會顯示const
  • 如果是連接查詢,被驅動表的執行計劃這裏會顯示驅動表的關聯字段
  • 如果是條件使用了表達式或者函數,或者條件列發生了內部隱式轉換,這裏可能顯示爲func
EXPLAIN select * from t_role r join t_role_user ru on r.id = ru.id 

在這裏插入圖片描述
從結果看,連接查詢,關聯的是r表的id字段。並且key_len爲8,說明定長的8個字節。
所以:key_len顯示的值爲索引字段的最大可能長度,並非實際使用長度,即key_len是根據表定義計算而得,不是通過表內檢索出的

rows


含義:返回估算的結果集數目,注意這並不是一個準確值。

extra


含義:包含不適合在其他列中顯示但十分重要的額外信息

  • Using index:查詢中使用了覆蓋索引(Covering Index)
    • 覆蓋索引:包含所有滿足查詢需要的數據的索引
    • 利用索引返回select列表中的字段,而不必根據索引再次讀取數據文件
    • 如果要使用覆蓋索引,一定要注意select列表中只取出需要的列,不可select *
EXPLAIN select age from t_user

在這裏插入圖片描述

  • Using where:用where子句來過濾結果集
EXPLAIN select * from t_user  where age = 1

在這裏插入圖片描述

  • Using filesort:使用文件排序,使用非索引列進行排序時出現,非常消耗性能,儘量優化。
EXPLAIN select * from t_user where age=3 order by creator

在這裏插入圖片描述

EXPLAIN select * from t_user where age=3 order by age

在這裏插入圖片描述

  • Using temporary:使用了臨時表,常見於排序和分組查詢
EXPLAIN select ru.user_no from t_role r join t_role_user ru on r.id = ru.id GROUP BY ru.user_no

在這裏插入圖片描述

EXPLAIN select r.role_name from t_role r join t_role_user ru on r.id = ru.id GROUP BY r.role_name

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章