explain優化sql
優化目的: 使用索引儘可能多的消除查詢數據行
方法: explain 後跟select 語句。根據查詢的結果中字段的值判斷sql的好壞。
例如: explain select * from test;
結果如下:
mysql> explain select * from student limit 1;
+----+-------------+---------+------+---------------+------+---------+------+------+-------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+---------+------+---------------+------+---------+------+------+-------+
| 1 | SIMPLE | student | ALL | NULL | NULL | NULL | NULL | 6 | |
+----+-------------+---------+------+---------------+------+---------+------+------+-------+
1 row in set (0.00 sec)
我們主要關注4個參數: type、key、rows、extra
關注1:type
表示mysql在表中找到所需行的方式,又稱“訪問類型,常見類型如下:
由左到右依次爲 由最差到最好,如圖:
all | index | range | index_subquery | unique_subquery | index_merge |
最壞(全表掃描) |
ref_or_null | ref | eq_ref | const | system |
最好 |
system表僅有一行(=系統表)。這是 const 連接類型的一個特例。
constconst 用於用常數值比較 PRIMARY KEY 時。當 查詢的表僅有一行時,使用 System。
eq_refconst 用於用常數值比較 PRIMARY KEY 時。當 查詢的表僅有一行時,使用 System。
ref連接不能基於關鍵字選擇單個行,可能查找 到多個符合條件的行。 叫做 ref 是因爲索引要 跟某個參考值相比較。這個參考值或者是一 個常數,或者是來自一個表裏的多表查詢的 結果值。
ref_or_null如同 ref, 但是 MySQL 必須在初次查找的結果 裏找出 null 條目,然後進行二次查找。
index_merge說明索引合併優化被使用了。
unique_subquery在某些 IN 查詢中使用此種類型,而不是常規的 ref:value IN (SELECT primary_key FROM single_table WHERE some_expr)
index_subquery在 某 些 IN 查 詢 中 使 用 此 種 類 型 , 與 unique_subquery 類似,但是查詢的是非唯一 性索引: value IN (SELECT key_column FROM single_table WHERE some_expr)
range只檢索給定範圍的行,使用一個索引來選擇 行。key 列顯示使用了哪個索引。當使用=、 <>、>、>=、<、<=、IS NULL、<=>、BETWEEN 或者 IN 操作符,用常量比較關鍵字列時,可 以使用 range。
index全表掃描,只是掃描表的時候按照索引次序 進行而不是行。主要優點就是避免了排序, 但是開銷仍然非常大。
all最壞的情況,從頭到尾全表掃描。
一般來說要能達到range級別,最好能達到ref級別,否則就可能存在性能問題。
關注2: key
顯示mysql在查詢中實際使用的索引,沒有則顯示null
關注3: rows
表示mysql根據表統計信息以及索引選用情況,估算找到所需記錄要讀取的行數
關注4:extra
如果是only index, 這意味着信息用索引樹中的信息檢索出的,這比掃描整個錶快。
如果是where used ,就是了where限制。
如果是impossible where 表示用不着where ,一般就是沒查出來啥。
如果此信息顯示Using filesort()或者 Using temporary(是用臨時表)的話會很吃力,where和order by的索引經常無法兼顧,如果按照where來確定索引,那麼order by時就會引起Using fileesort ,這就要看先過濾再排序,還是先排序再過濾了。
Using filesort表示 MySQL 會對結果使用一個外部索引排序,而不是從表裏按索引次序讀到相關內容。可能在內存或者磁盤上進行排序。MySQL 中無法利用索引完成的排序操作稱爲“文件排序”
Using temporary表示 MySQL 在對查詢結果排序時使用臨時表。常見於排序 order by 和分組查詢 group by。