文章目錄
explain幹嘛的?
explain(執行計劃):可以模擬 優化器 執行SQL查詢語句,並不會去真正的執行這條SQL,從而知道 MySQL 是如何處理你的SQL語句的。可用來分析你的查詢語句或是表結構的性能瓶頸。
作用
表的讀取順序
數據讀取操作的操作類型
哪些索引可以使用
哪些索引被實際使用
表之間的引用
每張表有多少行被優化器查詢
如何使用?
使用方法非常簡單,主要是要看的懂每個關鍵字的含義,下面將逐一的介紹每個關鍵字的作用。
explain + SQL語句
1、id
含義:select 查詢的系列號,表示查詢中執行 select 子句或操作表的順序
id常見的3種情況
1、id相同,執行順序從上到下
2、id不同,如子查詢,id的序號會遞增,id的值越大優先級越高,越先被執行
3、id相同不同都有,id值越大越先被執行,相同從上到下順序執行
來看一個小小的案例吧
判斷下列這個SQL的執行順序
答案:執行順序爲:4 ⇒ 3 ⇒ 2 ⇒ 1 ⇒ null
2、select_type
含義:表示該條SQL查詢的類型,如子查詢、聯合查詢等,常見值如下:
- simple
簡單的 select 查詢,查詢中不包含子查詢或 union - primary
查詢中若包含任何的子查詢,最外層的查詢被標記爲 primary - subquery
在 select 或 where 中包含子查詢 - derived
在 from 後包含的子查詢被標註爲 derived(衍生),MySQL 會遞歸執行這些子查詢,把結果放在臨時表裏 - union
若第二個 select 出現在 union 之後,則被標記爲 union,若 union 包含在 from 後面的子查詢中,外層的 select 將被標記爲:DERIVED - union result
從 union 表獲取結果的 select - update
更新 - insert
插入 - delete
刪除
table
含義:表示用到了哪幾張表,若出現了 derived 的情況,則表示產生了中間表,常見產生中間表的情況有子查詢和聯合查詢等。
type
type 顯示的是訪問類型,較爲重要
,結果值從最好到最壞依次爲:system > const > eq_ref > ref > range > index > all,一般來說,最好保證達到 range 級別,最好達到 ref
type的取值
-
system:
表中只有一行記錄(等同於系統表),這是const 類型的特列,平時不會出現,可以忽略不計 -
const:
表示通過索引一次就查找到了這條記錄,用於比較 primary key 或者 unique 索引,因爲只匹配一行數據,所以很快
如:將主鍵置於where後面,MySQL就能將該查詢轉換爲一個常量 -
eq_ref:
唯一索引掃描,對於每個索引建,表中只有一條記錄與之匹配。常見於主鍵或唯一索引掃描 -
ref:
非唯一索引掃描,返回匹配某個單獨值的所有行,本質也是一種索引訪問,它返回某個匹配值的多行數據 -
range:
只檢索指定範圍的行,使用一個索引來選擇行,一般就是在你的where語句中出現了between、<、>、in等的查詢,這種範圍掃描索引比全表掃描要好,因爲它只需要開始於索引的某一點,而結束於另一點,不用掃描全部索引 -
index:
full index scan,index 與 all 的區別爲 index 類型只遍歷索引樹,這通常比 all 快,因爲索引文件通常比數據文件小,也就是說 index 和 all 雖然都是讀全表,但index 是從索引中讀取的,而all使用硬盤中讀取 -
all:
full table scan,將遍歷全表以找到匹配的行
possible_keys
顯示可能
應用在這張表中的索引,一個或多個,但不一定實際用到,實際用到的在key上顯示
key
顯示實際用到的索引,每張表的一次查詢只會用到一個索引
key_len
顯示索引字段中使用的最大可能的字節數,並非實際的長度,可通過該參數計算查詢中使用的索引長度,在不損失精確性的情況下,長度越短越好,
ref
顯示哪些索引列或常量被引用了,優先 const,
rows
根據表統計信息及索引選用情況,大致估算出所優化的行數,越少越好
extra
包含不適合在其他列顯示但又十分重要的額外信息
常見值
-
Using filesort
文件內排序,即MySQL無法利用索引列進行排序,從而導致性能低下
一般出現在排序列未建索引或索引截斷的情況,效率差
常見索引截斷的情況(以下情況索引順序都爲:col1、col2、col3):
1、直接匹配col2
… order by col2
2、中間某一列沒使用,導致中間截斷
… where col1=“xxx” order by col3
3、使用範圍查找導致索引截斷
… where col1=‘xxx’ and col2>xxx order by col3 -
Using temporary
使用了臨時表保存中間結果,對查詢結果排序時使用了臨時表,常見於排序 order by 和分組查詢 group by。效率很差
-
using index
表示相應的select操作中使用了 覆蓋索引(Covering Index),避免訪問了表的數據行,效率不錯!
如果同時出現using where,表明索引被用來執行索引鍵值的查找;
如果沒有同時出現using where,表明索引只是用來讀取數據而非利用索引執行查找。 -
Using where
表明使用了where過濾 -
Using join buffer
使用了連接緩存, -
select tables optimized away
在沒有GROUPBY子句的情況下,基於索引優化MIN/MAX操作或者
對於MyISAM存儲引擎優化COUNT(*)操作,不必等到執行階段再進行計算,
查詢執行計劃生成的階段即完成優化。 -
distinct
優化 distinct 操作,在找到第一匹配的元組後即停止同樣值的操作
若有不當之處,望大佬指出!!!