mysql explain 詳解
在進行mysql語句分析或優化時,通常都會用到explain 語句,通過explain語句可以知道mysql的查詢邏輯和是否使用索引或者索引是否生效等信息。
語法格式:explain mysql語句
如:explain select * from account a right join account_order ao on a.id=ao.user_id where ao.user_id="0001";

字段說明:
id:select 標識符,這是mysql語句的執行順序。
select_type: select的查詢類型,分別為:
- SIMPLE 檢查select查詢(不使用union或子查詢)
- PRIMARY 最外面的select 查詢
- UNION union中的第二個或后面的select語句
- DEPENDENT UNION union中的第二個或后面的select語句,取決于外面的查詢
- UNION RESULT 從union臨時表檢索結果的select
- SUBQUERY 子查詢中的第一個select
- DEPENDENT SUBQUERY 子查詢中的第一個select,取決于外面的查詢
- DERIVED 導出表的select(from子句的子查詢)
table: 該查詢語句所對應的表名
type:聯接類型或訪問類型,分別為:
- system 表僅有一行(=系統表)。這是const聯接類型的一個特例。
- const 表中最多有一個匹配行,它將在查詢開始時被讀取。因為僅有一行,在這行的列值可被優化器剩余部分認為是常數。const表很快,因為它們只讀取一次!比如匹配主鍵索引或唯一索引時,當前匹配到1條記錄時,就停止之后的查詢。因此速度比較快。
- eq_ref 在多表查詢時,對于前、后表匹配時,后面的表僅匹配到1條記錄即結束之后的匹配。類似于const類型,因此,可以理解為在多表聯合查詢時,通過unique唯一索引或primary key主鍵索引進行關聯,和作為where的查詢條件,當前查詢到一條記錄后,就返回查詢結果并結束之后的匹配,因此在組合查詢時,也是查詢速度相對較好的。
- ref 普通索引查詢,也就是查詢條件不是主鍵索引或唯一索引,匹配的結果可能是一條或多條記錄,ref的查詢條件可以為索引字段=或<=>的操作符。
- ref_or_null 與ref類似,也是索引查詢,但是可以專門搜索包含null值的行,如where 索引字段=value or 索引字段 is null。
- index_merge 表示使用了索引合并優化方法,索引合并方法用于通過range掃描搜索行將結果合成一個。合并會產生并集、交集或者正在進行的掃描的交集的并集。
- unique_subquery 該類型表示使用了in 包含子查詢且子查詢根據主鍵索引或唯一索引進行查詢,如value in (select primary_key from table_name where some_expr)
- index_subquery 與unique_subquery類似,但是子查詢中引用的是非唯一索引。
- range 表示根據索引查詢某個條件范圍,可以使用=、<>、>、>=、<、<=、is null、<=>、between 或in 操作符來查詢。
- index 只匹配索引樹,通常比all類型快,因為索引文件通常比數據文件小,當查詢只使用作為單索引一部分的列時,mysql可以使用該類型。
- all 全表匹配,沒有根據索引進行匹配,當表的數據量很大時,查詢速度會很慢。
根據type類型效率按優排序為:system>const>eq_ref>ref>ref_or_null>index_merge>unique_subquery>index_subquery>range>index>all
possible_keys:表示mysql能使用哪個索引進行查詢,如果為null,則說明沒有相關索引。可以通過alter table 語法去建相應的索引。
key:表示mysql實際決定使用的索引,如果為null,說明該查詢沒有使用索引,比如當前已使用索引進行條件過濾,但是索引失效,則key的值會為null。
key_len:該列顯示mysql決定使用的鍵長度。如果鍵是null,則長度為null,注意通過key_len值我們可以確定mysql將實際使用一個多部關鍵字的幾個部分。
ref:顯示使用哪個列或常數與key一起從表中進行匹配。
rows:顯示msql認為它執行查詢時必須檢查的行數。
Extra:該列包含mysql解決查詢的詳細信息。對應的內容分別為:
- Distinct 表示mysql在發現第1個匹配行后,停止為當前的行組合匹配更多的行。
- Not exists 表示mysql能夠對查詢進行left join優化,發現1個匹配left join 標準的行后,不再為前面的行組合在該表內檢查更多的行。
- range checked for each record(index map:#) 表示mysql沒有發現好的可以使用的索引,但發現如果來自前面的表的列值已知,可能部分索引可以使用。對前面的表的每個行組合,mysql檢查是否可以使用range或index merge訪問方法來匹配行。
- using filesort 表示mysql需要額外的一次傳遞,以找出如何按排序順序檢索行。通過聯接類型瀏覽所有行并為所匹配where子句的行保保存排序關鍵字和行的指針來完成排序。然后關鍵字被排序,并按排序順序檢索行。
- using index 表示從只使用索引樹中的信息而不需要進一步搜索讀取實際的行來檢索表中的列信息。當查詢只使用作為單一索引部分的列時,可以使用該策略。
- using temporary 表示為了解決查詢,mysql需要創建一個臨時表來容納結果。典型情況如查詢包含可以按不同情況列出列的group by 或order by 子句時。
- using where 表示where子句用于限制哪一個行匹配下一個表或發送到客戶。除非你專門從表中索取或檢查所有行,如果extra值不為using where 并且表聯接類型為all或index ,查詢可能會有一些錯誤。如果想要使查詢盡可能快,應找出using filesort 和using temporary 的extra值。
- using sort_union(),using unoin() ,using intersect() 這些函數說明如何為index merge聯接類型合并索引掃描。
- using index for group-by 類似于訪問表的using index 方式,using index for group-by 表示mysql發現了一個索引,可以用來查詢group by 或distinct查詢的所有列,而不要額外搜索硬盤訪問實際的表。并且,按最有效的方式使用索引,以便對于每個組,只讀取少量索引條目。

浙公網安備 33010602011771號