一、Explain簡介:
Explain是用來分析SQL語句的運行結果,通過該命令可以獲取一下信息:表的讀取順序,數據庫讀取操作的操作類型,哪些索引可以使用,實際使用了哪些索引,表之間的引用,每張表有多少行別優化器查詢等信息。
二、體驗Explain執行效果
EXPLAIN SELECT
e.*,
d. NAME AS deparment_name,
d.id AS dpt_id,
u.channel_id,
u.id AS u_id
FROM
employee e
LEFT JOIN department AS d ON e.dep_id = d.id
LEFT JOIN users AS u ON e.id = u.obj_id
WHERE
(e.id = '146')
AND (e.flag = 1)
ORDER BY
e.id DESC
LIMIT 1
三、對Explain語句執行結果的每列進行說明
id
id
列的編號是select
的序列號,有幾個select
就有幾個id
,並且id的編號是按select
出現的順序增長的。如果沒有出現derived
等特殊語法,那麼explain
的執行順序是按照從上到下來執行的。
Mysql將select
查詢分爲簡單查詢和複雜查詢。複雜查詢分爲三類:簡單子查詢,派生表(from
語句中的子查詢)、union
查詢select type:
可以看執行實例,總共有以下幾種類型
SIMPLE
:表示查詢不包含UNION
或子查詢PRIMARY
:表示此查詢是最外層查詢SUBQUERY
:子查詢中的第一個SELECT
UINON
:表示此查詢是UINON
的第二或隨後的查詢DEPENDEND UINON
:UINON
中第二個或後面的查詢,取決於外層的查詢UINONR ESULT
:從union
臨時表檢索結果的select
DEPENDEND SUBQUERY
:子查詢的第一個SELEC
,取決於外面的查詢,即子查詢依賴於外層的查詢結果DERIVED
:衍生,表示導出標的select
(from
子句的子查詢)
table:
表示查詢設計的表和衍生的表
partitions:
如果查詢是基於分區的話,會顯示查詢將訪問的分區
type:
該字段比較重要,它提供了判斷查詢是否高效的重要依據。通過該字段我們可以判斷此次查詢是全表掃描還是索引掃描等
常用取值:system
:表中只有一條數據,這個類型是特殊的const
類型const
:針對主鍵或唯一索引的等值查詢掃描,最多隻返回一條數據。const
查詢速度非常快,因爲它僅僅 讀取一次即可eq_ref
:此類型通常出現在多表的join
查詢,表示對於前表的每一個結果,都只能匹配到後表的一個結果並且查詢的比較操作通常是=
,查詢效率較高。ref
:此類型通常出現在多表的join
查詢,針對於非唯一或非主鍵索引,或者使用了最左前綴規則索引的查詢。range
:表示使用了索引範圍查詢,通過索引字段範圍獲取表中部分記錄。這個類型通常出現在=,<>,>,>=,<,<=,IS NULL,<=>,BETWEEN,IN()
操作中。index
:表示全索引掃描(full index scan
),和ALL
類型類似,只不過ALL
類型是全表掃描,而index
類型則僅僅是掃描所有的索引,而不是掃描數據。index
通常出現在:索要查詢數據直接在索引樹鍾就可以獲取得到,而不需要掃描數據,當時這種情況下extra
字段會顯示Using index
ALL
:表示全表掃描,性能是最差的。通常來說, 我們的查詢不應該出現ALL
類型的查詢,因爲這樣的查詢在數據量大的情況下,對數據庫的性能是巨大的災難。 如一個查詢是ALL
類型查詢, 那麼一般來說可以對相應的字段添加索引來避免。
通常來說, 不同的 type 類型的性能關係如下:
ALL < index < range ~ index_merge < ref < eq_ref < const < system
ALL
類型因爲是全表掃描, 因此在相同的查詢條件下,它是速度最慢的。而index
類型的查詢雖然不是全表掃描,但是它掃描了所有的索引,因此比ALL
類型的稍快.後面的幾種類型都是利用了索引來查詢數據,因此可以過濾部分或大部分數據,因此查詢效率就比較高了。possible_keys:
它表示在mysql查詢時,可能用到的索引。
注意:即使有索引出現在 possible_keys
中出現,但並不表示此索引,真正的被mysql
使用到。mysql
使用了哪些索引,由key
字段決定key:
此字段是
mysql
查詢時真正使用到了索引。key_len:
表示查詢優化器使用了索引字節數,這個字段可以評估組合索引是否完全被使用
ref:
這個表示顯示索引的那一列被使用了,如果可能的話是一個常量。前文
type
屬性裏與ref
注意區別rows:
該字段也是一個重要的字段,
mysql
查詢優化器根據統計信息,估算sql
要查找到結果集需要掃描讀取的數據行數,這個值非常直觀的顯示sql效率好壞,原則上rows
越少越好。extra:
explain
中的很多額外的信息會在extra
字段顯示, 常見的有以下幾種內容:using filesort
:表示 mysql 需額外的排序操作,不能通過索引順序達到排序效果。一般有sing filesort
都建議優化去掉,因爲這樣的查詢cpu
資源消耗大。using index
:覆蓋索引掃描,表示查詢在索引樹中就可查找所需數據,不用掃描表數據文件,往往說明性能不錯。using temporary
:查詢有使用臨時表, 一般出現於排序, 分組和多表join
的情況, 查詢效率不高,建議優化。using where
:表名使用了where
過濾。
四、優化案例:
explain select * from orders where region_id=441900403
執行結果,type
有ALL
,並且沒有索引
開始優化,在region_id
列上創建索引,明顯看到type
列有ALL
變成ref
,並且用到了索引,rows
也從450933
行變成了16032
行