DB:使用EXPLAIN來分析DB狀態



explain SELECT user_id, user_loginID, user_pic 
FROM users 
WHERE user_loginID='user1234' AND user_password_encrypted='aaa1234' 
AND user_status=1;
+----+-------------+-------+-------+-------------------------------------------------------------+---------------------+---------+-------+------+-------+
| id | select_type | table | type  | possible_keys                                               | key                 | key_len | ref   | rows | Extra |
+----+-------------+-------+-------+-------------------------------------------------------------+---------------------+---------+-------+------+-------+
|  1 | SIMPLE      | users | const | user_loginID_UNIQUE,loginID_pw_index,loginID_emailcrc_index | user_loginID_UNIQUE | 50      | const |    1 | NULL  |
+----+-------------+-------+-------+-------------------------------------------------------------+---------------------+---------+-------+------+-------+
1 row in set (0.00 sec)

以上面的SELECT為例,EXPLAIN後的資料大約有這些欄位:

id: 
MySQL Query Optimizer 選定的執行計劃中查詢的序列號。
表示查詢中執行select子句或操作表的順序,id 值越大優先級越高,越先被執行。
id 相同,執行順序由上至下。

select_type
查詢的類型


查詢的類型 說明
SIMPLE 簡單的select 查詢,不使用union 及子查詢
PRIMARY Content Cell 最外層的select 查詢
UNION UNION 中的第二個或隨後的select 查詢,不依賴於外部查詢的結果集
DEPENDENT UNION UNION 中的第二個或隨後的select 查詢,依賴於外部查詢的結果集
SUBQUERY 子查詢中的第一個select 查詢,不依賴於外部查詢的結果集
DEPENDENT SUBQUERY 子查詢中的第一個select 查詢,依賴於外部查詢的結果集
DERIVED 用於from 子句裡有子查詢的情況。MySQL 會遞歸執行這些子查詢, 把結果放在臨時表裡
UNCACHEABLE SUBQUERY 結果集不能被緩存的子查詢,必須重新為外層查詢的每一行進行評估
UNCACHEABLE UNION UNION 中的第二個或隨後的select 查詢,屬於不可緩存的子查詢

table
關連到的資料表

type
使用關聯查詢的類型
(效率由好至壞排序)


關聯查詢的類型 說明
System 表僅有一行(=系統表),此為const連接類型的特殊情況
Const 資料表中的一個記錄的最大值能夠符合這個查詢。因為只有一行,這個值就是常數,因為MySQL會先讀這個值然後把它當做常數
eq_ref MySQL在連接查詢時,會從最前面的資料表,對每一個記錄的聯合,從資料表中讀取一個記錄,在查詢時會使用索引為主鍵或唯一鍵的全部
ref 只有在查詢使用了非唯一鍵或主鍵時才會發生。連接不能基於關鍵字選擇單個行,可能查找到多個符合條件的行。叫做ref 是因為索引要跟某個參考值相比較。這個參考值或者是一個常數,或者是來自一個表裡的多表查詢的結果值
fulltext
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 針對每一筆記錄進行完全掃描,此為最壞的情況,應該盡量避免

possible_keys
可能使用到的索引,從WHERE語法選擇出一個適合的欄位

key
MySQL 實際從possible_key 選擇使用的索引。
如果為NULL,則沒有使用索引。
很少的情況下,MYSQL 會選擇優化不足的索引。
這種情況下,可以在SELECT 語句中使用USE INDEX (indexname)來強制使用一個索引
或者用IGNORE INDEX(indexname)來強制MYSQL 忽略索引

key_len
使用索引的長度,長度越短,準確性越高

ref
顯示那一列的索引被使用,一般是一個常數(const)

rows
MySQL認為必須檢查的用來返回請求數據的行數,可以簡單的把rows視為執行效能,
越少越好

Extra
MySQL用來解析額外的查詢訊息
(效率由好至壞排序)


額外的查詢訊息 說明
Using where 使用WHERE語法中的欄位來返回結果
Using index 返回的資料是從索引中資料,而不是從實際的資料中返回,當返回的資料都出現在索引中的資料時就會發生此情況
Using filesort 表示MySQL會對結果使用一個外部索引排序,而不是從表裡按索引次序讀到相關內容。可能在內存或者磁盤上進行排序。MySQL 中無法利用索引完成的排序操作稱為“文件排序”。MySQL必須進行額外的步驟來進行查詢
Using temporary 此為MySQL必須建立一個暫時的資料表(Table)來儲存結果,此情況會發生在針對不同的資料進行ORDER BY和GROUP BY。

0 留言:

發佈留言