一、explain介紹
使用explain關鍵字可以模擬優化器執行sql查詢語句,從而就可以知道mysql是如何處理你的sql語句的,可以用來分析你的查詢語句或者是表結構的效能瓶頸。
通過explain我們可以分析出以下結果:
●表的讀取順序
●資料讀取操作的操作型別
●哪些索引可以使用
●哪些索引被實際使用
●表之間的引用
●每張表有多少行被優化器查詢
使用方式如下:
expalin +
sql語句
二、explain各列資訊含義列名
說明id
執行的編號,標識select所屬的行。如果在語句中沒有子查詢或者關聯查詢,只有唯一的select,每行都將顯示1。否則,內層的select語句一般會順序編號,對應於其在原始語句中的位置
select_type
顯示本行是簡單查詢或者是複雜查詢,如果查詢有任何複雜的子查詢,則最外層標記為primary(derived、union、union resuit)
table
資料的查詢訪問引用了哪個表
type
資料訪問/讀取的操作型別(all、index、range、ref、eq_ref、const、system、null)
possible_keys
顯示哪些索引可能有利於高效的資料查詢
key顯示優化器最終決定採用的索引
key_len
顯示使用索引中所使用的位元組數
ref顯示了之前的表在key列記錄的索引中查詢值所用的列或者常量
rows
為了找到所需的行而需要讀取的行數,估算值,不精確。通過把所有rows列值想乘,可粗略估算整個查詢會檢查的行數
extra
額外資訊,如using index、filesort等
1)id
id是用來順序標識整個查詢中select語句的編號,在巢狀查詢中id越大的語句越先執行。該值可能為null,那麼這一行用來說明的是其他行的聯合結果。
2)select_type
表示查詢的型別
型別說明
******
簡單子查詢,查詢中不包含子查詢和union
primary
包含union或者子查詢,最外層的部分標記為primary
subquery
在select或者where列表中包含了子查詢
derived
派生表,該臨時表是從子查詢中派生出來的,位於form中的子查詢
union
位於union中第二個及其以後的子查詢被標記為union,第乙個就被標記為primary,如果是union位於from中則標記為derived
union result
用來從匿名臨時表裡檢索結果的select被標記為union result
dependent union
顧名思義,首先需要滿足union的條件,及union中第二個以及後面的select語句,同時該語句依賴外部的查詢
dependent subquery
和dependent union相對union一樣
3)table
對應行正在訪問哪乙個表,表名或者別名。
●關聯優化器會為查詢選擇關聯順序,左側深度優先
●當form中有子查詢的時候,表名是derivedn的形式,n指向子查詢,也就是explain結果中的下一列
●當有union result的時候,表名是union 1,2等的形式,1,2表示參與union的query id
注意:mysql對待這些表和普通表一樣,但是這些"臨時表"是沒有任何索引的。
4)type
type顯示的是訪問型別,是較為重要的乙個指標,結果值從好到壞依次是:
system > const > eq_ref > ref > fulltext > req_or_null > index_merge > unique_subquery > index_subquery > range > index > all,一般來說,得保證查詢至少達到range級別,最好能夠達到ref。
型別說明
system
表只有一行記錄(等於系統表),這是const型別的特例
const
當確定查詢最多隻會有一行匹配的時候,mysql優化器會在查詢前讀取它並且只讀取一次,即通過索引一次就找到了資料,因此非常快。當主鍵放入where子句時,mysql會把這個查詢轉換為乙個常量(高效)
eq_ref
唯一性索引掃瞄,對於每個索引鍵,表中只有一條記錄與之匹配。常見於主鍵或唯一索引掃瞄
ref非唯一性索引掃瞄,返回匹配某個單獨值得所有行,本質上也是一種索引訪問,它返回所有匹配某個單獨值得行,然而,它可能會找到多個符合條件的行,所以它屬於查詢和掃瞄的混合體
range
只檢索給定範圍的行,使用乙個索引來選擇行,key列顯示使用了哪個索引,一般是在where語句**現between、<、>、in等的查詢中,這種範圍掃瞄索引比全表掃瞄要好,因為它只需要開始於索引的某一點,而結束於另一點不用做掃瞄全部索引
index
index和all的區別為index型別只遍歷索引樹,這通常比all要快,因為索引檔案通常比資料檔案小,也就是說all和index都是讀全表,但index是從索引中讀取的,而all是從硬碟中讀取的
all最壞的情況,將遍歷全表以找到匹配的行
5)possible_keys
顯示查詢使用了哪些索引,表示該索引可以進行高效的查詢,但是列出來的索引對於後續優化過程可能是沒有用的。
6)key
key列顯示了mysql優化器實際上所決定使用的鍵(索引),如果沒有選擇索引,鍵是null。要想mysql使用或者忽視possible_keys列中的索引,在查詢中使用force index、use index或者ignore index。
7)key_len
表示索引中使用的位元組數,可通過該列計算查詢中使用的索引的長度,在不損失精確性的情況下,長度越短越好。key_len顯示地值為索引欄位的最大可能長度,並非實際使用長度,即key_len是根據表定義計算而得,不是通過表內檢索出的。
8)ref
顯示索引的那一列被使用了,如果可能的話,最好是乙個常數。哪些列或者常量被用於查詢索引列上的值。
9)rows
rows列顯示mysql認為它執行查詢時必須檢查的行數,注意這是乙個預估值。
10)extra
extra是explain輸出中另外乙個很重要的列,該列顯示mysql在查詢過程中的一些詳細資訊,mysql查詢優化器執行查詢的過程中對查詢計畫的重要補充資訊。
型別說明
using filesoft
mysql有兩種方式可以生成有序的結果,通過排序操作或者使用索引,當extra**現了using filesoft說明mysql使用了後者,但注意雖然叫filesoft但並不是說明就是用了檔案來進行排序,只要可能排序 都是在記憶體裡完成的。大部分情況下利用索引排序更快,所以一般這時也要考慮優化查詢了。使用檔案完成排序操作,這是可能是order by,group by語句的結果,這可能是乙個cpu密集型的過程,可以通過選擇合適的索引來改進效能,用索引來為查詢結果排序。
using temporary
用臨時表儲存中間結果,常用於group by和order by操作中,一般看到它說明查詢需要優化了,就算避免不了臨時表的使用也要盡量避免硬碟臨時表的使用。
not exists
mysql優化了left join,一旦它找到了匹配left join標準的行,就不再搜尋了
using index
說明查詢是覆蓋了索引的,不需要讀取資料檔案,從索引樹(索引檔案)中即可獲得資訊,如果同時出現using where,表明索引被用來執行索引鍵值的查詢,沒有using where,表明索引被用來執行索引鍵值的查詢,沒有using where,表明索引用來讀取資料而非執行查詢動作。這是mysql服務層完成的,但無需再回表查詢記錄
using index condition
這是mysql 5.6出來的新特性,叫做"索引條件推送"。簡單說就是mysql原來在索引上是不能執行如like這樣的模糊匹配操作的,但是現在可以了,這樣減少了不必要的io操作,但是只能用在二級索引上。
using where
using join buffer
使用了連線快取:block nested loop,連線演算法是塊巢狀迴圈連線;batched key access,連線演算法是批量索引連線
impossible where
where子句的值總是false,不能用來獲取任何元組
select tables optimized away
在每有group by子句的情況下,基於索引優化min/max操作,或者對於myisam儲存引擎優化count(*)操作,不必等到執行階段再進行計算,查詢執行計畫生成的階段即完成優化。
distinct
優化distinct操作,在找到第乙個匹配的元組後即停止找同樣值得動作
mysql中索引利用情況(explain用法)
使用explain檢視,如下 1 首先建立表test,語句如下 sql view plain copy create table test a int,b varchar 10 c varchar 10 2 在表中的a,b都建立索引,先後順序是a,b sql view plain copy crea...
mysql 中explain的用法
最近在做效能測試中經常遇到一些資料庫的問題,通常使用慢查詢日誌可以找到執行效果比較差的sql,但是僅僅找到這些sql是不行的,我們需要協助開發人員分析問題所在,這就經常用到explain explain顯示了mysql如何使用索引來處理select語句以及連線表。可以幫助選擇更好的索引和寫出更優化的...
mysql中explain的用法
mysql中explain的用法 最近在做效能測試中經常遇到一些 資料庫的問題,通常使用慢查詢日誌可以找到執行效果比較差的sql,但是僅僅找到這些sql是不行的,我們需要協助開發人員分析問題所在,這就經常用到explain explain顯示了 mysql如何使用索引來處理select語句以及連線表...