近期有個產品的統計信息超過了2000萬行,後臺的查詢直接超時了,單純sql在命令行執行都須要20s以上。用EXPLAIN後發現由於索引太多這條SQL沒有用上計劃的索引,更改後直接秒級出結果,下面看看EXPLAIN(Navicat裏的解釋按鈕一樣效果)的威力。
explain執行後的效果大體以下:html
mysql> explain select * from student where classid=1; +----+-------------+---------+------------+------+---------------+------+---------+------+------+----------+-------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+---------+------------+------+---------------+------+---------+------+------+----------+-------------+ | 1 | SIMPLE | student | NULL | ALL | NULL | NULL | NULL | NULL | 4 | 25.00 | Using where | +----+-------------+---------+------------+------+---------------+------+---------+------+------+----------+-------------+ 1 row in set, 1 warning (0.00 sec)
總共有12列,分別是id、select_type、table、partitions、type、possible_keys、key、key_len、ref、rows、filtered、Extra,其中在我看來最重要的是key列和extra列。
key直接顯示有沒有使用索引,extra顯示是否根據條件查詢、有沒有利用文件排序等。
可以把SQL優化(修改)到使用索引基本上就能夠通吃絕大多數狀況了。mysql
列名 | 解釋 |
---|---|
id | 查詢的惟一標識 |
select_type | 查詢類型 |
table | 查詢的那個表 |
partitions | 匹配的分區 |
type | join類型 |
possible_keys | 可能使用的索引 |
key | 最終使用的索引 |
key_len | 最終使用的索引的長度 |
ref | 與索引一塊兒被使用的字段或常數 |
rows | 查詢掃描的行數,是個估算值 |
filtered | 查詢條件所過濾的數據的百分比 |
Extra | 額外的信息 |
查詢的惟一標識,當這行是聯合查詢中的被驅動的表時這個值是Null。web
值 | 解釋 |
---|---|
SIMPLE | 表示此查詢不包含 UNION 查詢或子查詢 |
PRIMARY | 表示此查詢是最外層的查詢 |
UNION | 表示此查詢是 UNION 的第二或隨後的查詢 |
DEPENDENT UNION | UNION 中的第二個或後面的查詢語句, 取決於外面的查詢 |
UNION RESULT | UNION 的結果 |
SUBQUERY | 子查詢中的第一個 SELECT |
DEPENDENT SUBQUERY | 子查詢中的第一個 SELECT, 取決於外面的查詢. 即子查詢依賴於外層查詢的結果 |
DERIVED | 驅動表 |
MATERIALIZED | 子查詢的實現(Materialized subquery) |
UNCACHEABLE SUBQUERY | 不能被緩存的子查詢 |
UNCACHEABLE UNION | 在聯合查詢中的且不能被緩存的子查詢中的後續查詢 |
查詢涉及的表名。算法
查詢的記錄所在的分區,若是表沒有被拆分這個值是Null。sql
鏈接的類型,不一樣的類型及說明以下:緩存
值 | 解釋 |
---|---|
system | 這是下面類型const的一種特殊狀況。表裏只有一條數據。 |
const | 針對主鍵或者索引的等值查詢,該表最多有一個匹配的行,因爲只有一行,所以該行中列的值能夠被優化器的其他部分視爲常量。 |
eq_ref | 當鏈接使用索引的全部部分而且索引是a PRIMARY KEY或UNIQUE NOT NULL索引時。 |
ref | 全部具備匹配索引值的行都從這個表中讀取 |
fulltext | 使用FULLTEXT 索引執行 |
ref_or_null | ref的基礎上包含了NULL值的搜索 |
index_merge | 使用索引合併優化 |
unique_subquery | 只是一個索引查找函數,能夠徹底替代子查詢以提升效率。 |
index_subquery | 取代了IN子查詢,但它適用於非惟一索引的子查詢。 |
range | 只有在給定範圍內的行才能被檢索,使用索引來選擇行。的key 輸出行中的列指示使用哪一個索引。將key_len包含已使用的時間最長的關鍵部分。該ref列是 NULL用於這種類型的。 |
index | 使用索引查找,如在Extra列看到Using index,說明正在使用覆蓋索引,只掃描索引的數據,它比按索引次序全表掃描的開銷要小不少 |
ALL | 全表掃描 |
可能被使用的索引,若是此列是NULL,則表示沒有相關的索引,能夠經過WHERE 子句來檢查是否引用某些適合索引或列,從而提升查詢的性能。
要查看錶有哪些索引,請使用 SHOW INDEX FROM tbl_name
服務器
上面的possible_keys是可能被使用的key,這個式實際被使用的鍵。
若是 key是NULL,表示MySQL沒有發現有索引能夠用於更有效地執行查詢。要強制MySQL使用索引或忽略索引,可使用FORCE INDEX,USE INDEX
或IGNORE INDEX
語句。函數
被使用索引的長度。取決於key列,若是key爲NULL,這列也是NULL。oop
該列顯示將哪些列或常量與列中指定的索引進行比較,以 key從表中選擇行。性能
MySQL認爲查詢必須掃描的行數。
對於InnoDB存儲引擎,這個數字是估計值,並不老是準確的。
條件過濾後的行佔表內總行數的百分比。
表示MySQL解析查詢的其餘信息。
Extra是EXPLAIN輸出中另一個很重要的列,該列顯示MySQL在查詢過程當中的一些詳細信息,MySQL查詢優化器執行查詢的過程當中對查詢計劃的重要補充信息。
值 | 解釋 |
---|---|
Using filesort | MySQL有兩種方式能夠生成有序的結果,經過排序操做或者使用索引,當Extra中出現了Using filesort 說明MySQL使用了後者,但注意雖然叫filesort但並非說明就是用了文件來進行排序,只要可能排序都是在內存裏完成的。大部分狀況下利用索引排序更快,因此通常這時也要考慮優化查詢了。使用文件完成排序操做,這是多是ordery by,group by語句的結果,這多是一個CPU密集型的過程,能夠經過選擇合適的索引來改進性能,用索引來爲查詢結果排序。 |
Using temporary | 用臨時表保存中間結果,經常使用於GROUP BY 和 ORDER BY操做中,通常看到它說明查詢須要優化了,就算避免不了臨時表的使用也要儘可能避免硬盤臨時表的使用。 |
Not exists | MYSQL優化了LEFT JOIN,一旦它找到了匹配LEFT JOIN標準的行, 就再也不搜索了。 |
Using index | 說明查詢是覆蓋了索引的,不須要讀取數據文件,從索引樹(索引文件)中便可得到信息。若是同時出現using where,代表索引被用來執行索引鍵值的查找,沒有using where,代表索引用來讀取數據而非執行查找動做。這是MySQL服務層完成的,但無需再回表查詢記錄。 |
Using index condition | 這是MySQL 5.6出來的新特性,叫作「索引條件推送」。簡單說一點就是MySQL原來在索引上是不能執行如like這樣的操做的,可是如今能夠了,這樣減小了沒必要要的IO操做,可是隻能用在二級索引上。 |
Using where | 使用了WHERE從句來限制哪些行將與下一張表匹配或者是返回給用戶。注意:Extra列出現Using where表示MySQL服務器將存儲引擎返回服務層之後再應用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操做,在找到第一匹配的元組後即中止找一樣值的動做。 |
參考
http://www.searchdoc.cn/rdbms/mysql/dev.mysql.com/doc/refman/5.7/en/explain-output.com.coder114.cn.html#explain-extra-information
https://www.jianshu.com/p/ea3fc71fdc45
http://www.deituicms.com/mysql8cn/cn/web.html