MySQL的Explain執行計劃可以用來對Sql語句進行分析,是否進行全表掃描,是否用了索引,或者是sql語句先後執行計劃,有沒有用臨時表等等,由此來進行Sql優化,而show Profile和Explain一樣都是用來查看Sql語句分析的,但是形式不一樣,show Profile用來分析當前會話語句執行的資源消耗情況,能清晰的知道sql執行過程,以及過程中消耗的時間。
那麼咱們先來說一下Explain執行計劃
這是執行Explain命令後顯示的信息,那麼不熟悉的就會對此比較陌生,下面來一一講解每個列的說明。
1.Explain各字段含義
1.1 id列
id列的編號是select的序列號,表示查詢中執行select子句或操作表的順序
id序列數不同,如果是子查詢的話,則id值越大優先級越高,越先被執行
id序列數相同,則執行順序由上到下
id既有相同又有不同的,視爲相同的一組,執行順序由上到下,不同的id序列數越大,優先值越高
1.2 select_type列
select_type是查詢類型,說明查詢的種類
1.SIMPLE:簡單查詢,查詢不包含子查詢和UNION。
2.PRIMARY:複雜查詢包含含子部分,最外層查詢則被標記爲PRIMARY
3.DERIVED(form型子查詢):包含在from子句中的子查詢。MySQL會將結果存放在一個臨時表中,也稱爲派生表.
4.UNION:在UNION中第二個隨後的select
5.UNION RESULT:從UNION臨時表檢索結果的select(如果無需要儘量少寫union,因爲使用的是臨時表,所以不能進行索引優化)
6.DEPENDENT UNION:UNION語句中的第二個SELECT,依賴於外部子查詢 (暫時沒有寫到出現DEPENDENT UNION的sql所以沒有示例)
7.SUBQUERY(非form子查詢):包含在select中的子查詢。
8.DEPENDENT SUBQUERY:子查詢中的第一個SELECT,取決於外面的子查詢
1.3 table列
指的就是當前執行的表
1.4 partitions列
分區表
1.5 type列
type所顯示的是查詢使用了哪種類型,即MySQL決定如何查找表中的行。以下是按執行效率排序,優化最好是能優化最高的。
1.system:表只有一行記錄(等於系統表),這是const類型的特例,平時不會出現,這個也可以忽略不計。標紅的常用經常出現的
2.const:MySQL能對查詢的某部分進行優化並將其轉化爲一個常量,const 用於比較primary key 或者unique索引。因爲只匹配一行數據所以很快,一般用於主鍵刷選
3.eq_ref:primary key 或 unique key 索引的所有部分被連接使用,最多隻會返回符合條件的記錄,這可能是const之外最好的連接類型了,簡單的select查詢不會出現這種type(一般用於關聯查詢),唯一性索引掃描,對於每個索引鍵,表中只有一條記錄與之匹配。常見於主鍵或唯一索引掃描
4.ref:相比eq_ref,不使用唯一索引,而是使用普通索引或者唯一性索引的部分前綴,索引要和某個值相比較,可能會找到多個符合條件的行(非主鍵非唯一性索引的數據檢索)非唯一性索引掃描,返回匹配某個單獨值的所有行,本質上也是一種索引訪問,它返回所有匹配某個單獨值的行,然而,它可能會找到多個符合條件的行,所以他應該屬於查找和掃描的混合體。
5.fulltex:
6.ref_or_null:類似ref,但是可以搜索值爲null的行
示例: 運行explain select * from film where name = "film1" or name is null;
7.index_merge:多重範圍掃描,兩表連接的每個表的連接字段上均有索引存在且索引有序,結果合併在一起,適用於做集合的並、交操作。
8.unique_subquery:在子查詢中基於唯一索引進行掃描,類似於eq_ref
9.index_ subquery:在子查詢中基於除唯一索引之外的索引進行掃描
10.range:只檢索給定範圍的行,使用一個索引來選擇行,key列顯示使用了哪個索引,一般在where語句中會出現between,>,<,in等查詢,這種範圍掃描索引比全表掃描好,因爲它只需要開始於索引的某一個點,而結束於另一點,不用掃描全部索引。Range性能飄忽不定的,主要是看範圍給定的多少,數值大,掃描多,數值小,掃描小(範圍檢索)
11.index:index是基於索引樹進行全表掃描,所以通常比ALL快,因爲索引文件通常比數據文件小。index是從索引中讀取多的,all是從硬盤中讀取的
12.ALL:全表掃描,意味着mysql從頭到尾去查找所需要的行。通常情況下需要增加索引來進行優化了。不使用索引,順序掃描,直接讀取表上的數據(訪問數據文件)
示例: 運行explain select * from actor;
13.INDEX_SCAN: 索引做掃描,是基於索引在索引的葉子節點上找滿足條件的數據(不需要訪問數據文件)
1.6 possible_key列
這一列顯示查詢可能使用哪些索引來查找(備選項),不是實際使用的。
1.7 key列
這一列顯示mysql實際採用哪個索引來優化對該表的訪問。
1.8 key_len列
這一行顯示了MySQL在索引(key)裏使用的字節數,可通過該列計算查詢中使用的索引的長度,在不損失精確性的情況下,長度越短越好,key_len顯示的值爲索引字段的最大可能長度,並非實際使用長度,即key_len是根據表定義計算而得,不是通過表內檢索出的
1.9 ref列
這一列顯示了在key列記錄的索引中,表查找值所用到的列或常量,常見的有:const(常量),func,NULL,字段名(例:film.id
通過type知道主外鍵關係,通過key主鍵索引知道ref的哪個表關聯,也知道哪個字段與之關聯對應
1.10 rows列
根據表統計信息及索引選用情況,大致估算出找到所需的記錄所需要讀取的行數,也就是說,用的越少越好
1.11 filtered列
是一個百分比的值,代表(rows * filtered)/100,這個結果將於前表產生交互
1.12 Extra列
這一列展示的是除解釋語句以外的額外信息,也是十分重要的信息
1.distinct:優化distinct操作,在找到第一匹配的元素後即停止找同樣值的動作。
2.Using index(效率很好):表示相應的select操作中使用了覆蓋索引(Covering index),避免訪問了表的數據行,是性能高的表現,如果同時出現using where,表明索引被用來執行索引鍵值的查找;如果沒有同時出現using where,表明索引用來讀取數據而非執行查找動作。
同時出現Using Where 表明索引被用來執行索引鍵值的查找
沒有同是出現Using where 表明索引用來讀取數據而非執行查找動作
引申一下,覆蓋索引在我的博客 MySQL性能優化(三)--MySQL索引詳細介紹(乾貨滿滿)有講到,在這裏放一個小小的鏈接
https://blog.csdn.net/dfBeautifulLive/article/details/103202803
3.Using where:MySQL服務器將在存儲引擎檢索行後再進行過濾,就是先讀取整行數據,再按where條件進行檢查,符合就留下,不符合就丟棄。
4.Using filesort(效率很差):MySQL會對數據使用一個外部的索引排序,而不是按照表內的索引順序進行讀取,MySQL中無法利用索引完成的排序操作稱爲"文件排序"
5.Using temporary(效率更差):使用了臨時表保存中間結果,出現這種情況一般都需要進行優化,MySQL在對查詢結果排序時使用臨時表。常見於排序order by和分組查詢group by。
6.Using join buffer:表明使用了連接緩存,比如說在查詢的時候多表join的次數非常多,那麼將配置文件中的緩衝區的join buffer調大一些。
7.impossible where:where子句的值總是false,不能用來獲取任何元素
2.show Profile SQL分析
SHOW PROFILE 是MySQL提供可以用來分析當前會話語句執行的資源消耗情況,可以用於SQL 的調優測評依據,
SHOW VARIABLES LIKE 'PROFILING'通過這個命令查看參數開關情況
如果是關閉的可以通過這個命令設置開啓SET PROFILING = ON;
也可以通過select @@have_profiling命令查看MySQL是否支持profile;
如果是profiling是關閉的,通過Set語句開啓 set profiling=1;
通過show profiles 查詢最近15次運行結果
比如我查詢這個sql語句,select count(*) from registered_kj_resourcegroup_type,查詢完畢執行show profiles命令,那麼咱們剛纔執行的sql情況就出來了
Query_ID屬性:表示從連接上數據庫到現在執行的SQL 語句序號
Duration屬性:表示執行該SQL 所耗費的時間(S)
Query屬性:表示執行的操作
通過show profile for query 285語句能夠看到執行過程中線程的每個狀態和消耗的時間:
注意: Sending data狀態表示MySQL線程開始訪問數據行並把結果返回給客戶端,而不僅僅是返回結果給客戶端。
由於在Sending data狀態下,MySQL線程往往需要做大量的磁盤讀取操作,所以經常是整個查詢中耗時最長的狀態。
如果對MySQL源碼感興趣可以通過show profile source for query查看SQL解析執行過程中每個步驟對應的源碼文件、函數名以及具體的源文件行數。
如命令:show profile source for query 310
Source_function屬性:函數名稱
Source_file屬性:源文件
Source_line屬性:源文件行數