前言
只有光頭才能變強html
刷面試題的時候,不知道大家有沒有見過MySQL這兩個命令:explain
和profile
(反正我就見過了)..mysql
以前雖然知道這兩個命令大概什麼意思,但一直沒有去作筆記。今天發現本身的TODO LIST
有這麼兩個命令,因而打算來學習一番,記錄一下~git
使用的MySQL的版本爲5.6.38
github
1、explain命令
1.1體驗explain命令
首先咱們來體驗一下explain
命令是怎麼使用的,以及輸出的結果是什麼:面試
explain select * from table_user ;
輸出結果:sql
發現很使用起來很簡單,只要explain後邊跟着SQL語句就完事了(MySQL5.6以前的版本,只容許解釋SELECT
語句,從 MySQL5.6開始,非SELECT
語句也能夠被解釋了)。數據庫
1.2爲何須要explain命令
咱們不少時候編寫完一條SQL語句,每每想知道這條SQL語句執行是否高效。或者說,咱們創建好的索引在這條SQL語句中是否使用到了,就可使用explain
命令來分析一下!緩存
- 簡單來講:經過
explain
命令咱們能夠學習到該條SQL是如何執行的,隨後解析explain的結果能夠幫助咱們使用更好的索引,最終來優化它!
經過explain
命令咱們能夠知道如下信息:表的讀取順序,數據讀取操做的類型,哪些索引可使用,哪些索引實際使用了,表之間的引用,每張表有多少行被優化器查詢等信息。性能
// 好了,咱們下面看一下explain出來的結果是怎麼看的。
學習
1.3讀懂explain命令結果
explain命令輸出的結果有10列:id、select_type、table、type、possible_keys、key、key_len、ref、rows、Extra
1.3.1id
包含一組數字,表示查詢中執行SELECT子句或操做表的順序。
在id列上也會有幾種狀況:
- 若是id相同執行順序由上至下。
- 若是id不相同,id的序號會遞增,id值越大優先級越高,越先被執行。
1.3.2select_type
表示select查詢的類型
select_type屬性下有好幾種類型:
- SIMPLLE:簡單查詢,該查詢不包含 UNION 或子查詢
- PRIMARY:若是查詢包含UNION 或子查詢,則最外層的查詢被標識爲PRIMARY
- UNION:表示此查詢是 UNION 中的第二個或者隨後的查詢
- DEPENDENT:UNION 知足 UNION 中的第二個或者隨後的查詢,其次取決於外面的查詢
- UNION RESULT:UNION 的結果
- SUBQUERY:子查詢中的第一個select語句(該子查詢不在from子句中)
- DEPENDENT SUBQUERY:子查詢中的 第一個 select,同時取決於外面的查詢
- DERIVED:包含在from子句中子查詢(也稱爲派生表)
- UNCACHEABLE SUBQUERY:知足是子查詢中的第一個 select 語句,同時意味着 select 中的某些特性阻止結果被緩存於一個 Item_cache 中
- UNCACHEABLE UNION:知足此查詢是 UNION 中的第二個或者隨後的查詢,同時意味着 select 中的某些特性阻止結果被緩存於一個 Item_cache 中
類型有點多啊,我加粗的是最多見的,起碼要看得懂加粗的部分。
1.3.3table
該列顯示了對應行正在訪問哪一個表(有別名就顯示別名)。
當from子句中有子查詢時,table列是 <derivenN>
格式,表示當前查詢依賴 id=N
的查詢,因而先執行 id=N
的查詢
1.3.4type
該列稱爲關聯類型或者訪問類型,它指明瞭MySQL決定如何查找表中符合條件的行,同時是咱們判斷查詢是否高效的重要依據。
如下爲常見的取值
- ALL:全表掃描,這個類型是性能最差的查詢之一。一般來講,咱們的查詢不該該出現 ALL 類型,由於這樣的查詢,在數據量最大的狀況下,對數據庫的性能是巨大的災難。
- index:全索引掃描,和 ALL 類型相似,只不過 ALL 類型是全表掃描,而 index 類型是掃描所有的索引,主要優勢是避免了排序,可是開銷仍然很是大。若是在 Extra 列看到 Using index,說明正在使用覆蓋索引,只掃描索引的數據,它比按索引次序全表掃描的開銷要少不少。
- range:範圍掃描,就是一個有限制的索引掃描,它開始於索引裏的某一點,返回匹配這個值域的行。這個類型一般出如今
=、<>、>、>=、<、<=、IS NULL、<=>、BETWEEN、IN()
的操做中,key 列顯示使用了哪一個索引,當 type 爲該值時,則輸出的 ref 列爲 NULL,而且 key_len 列是這次查詢中使用到的索引最長的那個。
- ref:一種索引訪問,也稱索引查找,它返回全部匹配某個單個值的行。此類型一般出如今多表的 join 查詢, 針對於非惟一或非主鍵索引, 或者是使用了最左前綴規則索引的查詢。
- eq_ref:使用這種索引查找,最多隻返回一條符合條件的記錄。在使用惟一性索引或主鍵查找時會出現該值,很是高效。
- const、system:該表至多有一個匹配行,在查詢開始時讀取,或者該表是系統表,只有一行匹配。其中 const 用於在和 primary key 或 unique 索引中有固定值比較的情形。
- NULL:在執行階段不須要訪問表。
1.3.5possible_keys
這一列顯示查詢可能使用哪些索引來查找
1.3.6key
這一列顯示MySQL實際決定使用的索引。若是沒有選擇索引,鍵是NULL。
1.3.7key_len
這一列顯示了在索引裏使用的字節數,當key列的值爲 NULL 時,則該列也是 NULL
1.3.8ref
這一列顯示了哪些字段或者常量被用來和key配合從表中查詢記錄出來。
1.3.9rows
這一列顯示了估計要找到所需的行而要讀取的行數,這個值是個估計值,原則上值越小越好。
1.3.10extra
其餘的信息
常見的取值以下:
- Using index:使用覆蓋索引,表示查詢索引就可查到所需數據,不用掃描表數據文件,每每說明性能不錯。
- Using Where:在存儲引擎檢索行後再進行過濾,使用了where從句來限制哪些行將與下一張表匹配或者是返回給用戶。
- Using temporary:在查詢結果排序時會使用一個臨時表,通常出現於排序、分組和多表 join 的狀況,查詢效率不高,建議優化。
- Using filesort:對結果使用一個外部索引排序,而不是按索引次序從表裏讀取行,通常有出現該值,都建議優化去掉,由於這樣的查詢 CPU 資源消耗大。
最後
本來覺得Explain命令是比較難學的,但查找資料看下來,以前只是不知道具體的列和列中下的屬性是什麼意思而已。常見出現的其實也就那麼幾個,感受對着每一個屬性多看一會,仍是能夠能看懂的。
固然了,在《高性能MySQL》中也有複雜的SQL語句來分析(但我認爲咱們通常不會寫到那麼複雜)..
這篇文章也借鑑了不少其餘優秀的博客,若是你們有興趣的話能夠去閱讀一下:
- EXPLAIN 命令詳解:
- MySQL Explain 命令詳解:
- mysql系列_explain執行計劃:
- MySQL explain詳解
若是你以爲我寫得還不錯,瞭解一下:
- 堅持原創的技術公衆號:Java3y。回覆 1 加入Java羣
- 文章的目錄導航(精美腦圖+海量視頻資源):