Mysql explain用法和效能分析
MySQL中EXPLAIN解釋命令是顯示mysql如何使用索引來處理select語句以及連線表。可以幫助選擇更好的索引和寫出更優化的查詢語句。
使用方法很簡單,就是在select語句前加上explain, 如下:
1. 使用explain語句去檢視分析結果,如
explain select * from test1 where id=1;
會出現以下
id selecttype table type possible_keys key key_len ref rows extra
EXPLAIN列的解釋:
table:顯示這一行的資料是關於哪張表的
type:這是重要的列,顯示連線使用了何種型別。從最好到最差的連線型別為const、eq_reg、ref、range、indexhe和ALL
possible_keys:顯示可能應用在這張表中的索引。如果為空,沒有可能的索引。可以為相關的域從WHERE語句中選擇一個合適的語句
key: 實際使用的索引。如果為NULL,則沒有使用索引。很少的情況下,MYSQL會選擇優化不足的索引。這種情況下,可以在SELECT語句中使用USE INDEX(indexname)來強制使用一個索引或者用IGNORE INDEX(indexname)來強制MYSQL忽略索引
key_len:使用的索引的長度。在不損失精確性的情況下,長度越短越好
ref:顯示索引的哪一列被使用了,如果可能的話,是一個常數
rows:MYSQL認為必須檢查的用來返回請求資料的行數
Extra:關於MYSQL如何解析查詢的額外資訊。將在表4.3中討論,但這裡可以看到的壞的例子是Using temporary和Using filesort,意思MYSQL根本不能使用索引,結果是檢索會很慢
extra列返回的描述的意義
Distinct:一旦MYSQL找到了與行相聯合匹配的行,就不再搜尋了
Not exists: MYSQL優化了LEFT JOIN,一旦它找到了匹配LEFT JOIN標準的行,就不再搜尋了
Range checked for each Record(index map:#):沒有找到理想的索引,因此對於從前面表中來的每一個行組合,MYSQL檢查使用哪個索引,並用它來從表中返回行。這是使用索引的最慢的連線之一
Using filesort: 看到這個的時候,查詢就需要優化了。MYSQL需要進行額外的步驟來發現如何對返回的行排序。它根據連線型別以及儲存排序鍵值和匹配條件的全部行的行指標來排序全部行
Using index: 列資料是從僅僅使用了索引中的資訊而沒有讀取實際的行動的表返回的,這發生在對錶的全部的請求列都是同一個索引的部分的時候
Using temporary 看到這個的時候,查詢需要優化了。這裡,MYSQL需要建立一個臨時表來儲存結果,這通常發生在對不同的列集進行ORDER BY上,而不是GROUP BY上
Where used 使用了WHERE從句來限制哪些行將與下一張表匹配或者是返回給使用者。如果不想返回表中的全部行,並且連線型別ALL或index,這就會發生,或者是查詢有問題不同連線型別的解釋(按照效率高低的順序排序)
system 表只有一行:system表。這是const連線型別的特殊情況
const:表中的一個記錄的最大值能夠匹配這個查詢(索引可以是主鍵或惟一索引)。因為只有一行,這個值實際就是常數,因為MYSQL先讀這個值然後把它當做常數來對待
eq_ref:在連線中,MYSQL在查詢時,從前面的表中,對每一個記錄的聯合都從表中讀取一個記錄,它在查詢使用了索引為主鍵或惟一鍵的全部時使用
ref:這個連線型別只有在查詢使用了不是惟一或主鍵的鍵或者是這些型別的部分(比如,利用最左邊字首)時發生。對於之前的表的每一個行聯合,全部記錄都將從表中讀出。這個型別嚴重依賴於根據索引匹配的記錄多少—越少越好
range:這個連線型別使用索引返回一個範圍中的行,比如使用>或<查詢東西時發生的情況
index: 這個連線型別對前面的表中的每一個記錄聯合進行完全掃描(比ALL更好,因為索引一般小於表資料)
ALL:這個連線型別對於前面的每一個記錄聯合進行完全掃描,這一般比較糟糕,應該儘量避免
其中,
type=const 表示通過索引一次就找到了,
key=primary 表示使用了主鍵
type=all, 表示為全表掃描,
key=null 表示沒用到索引;
type=ref, 因為這時認為是多個匹配行,在聯合查詢中,一般為REF
2 MYSQL中的組合索引
假設表有id,key1,key2,key3,把三者形成一個組合索引,則
如:
where key1=….
where key1=1 and key2=2
where key1=3 and key3=3 and key2=2
根據最左原則,這些都是可以使用索引的哦
如
from test where key1=1 order by key3
用explain分析的話,只用到了normal_key索引,但只對where子句起作用,而後面的order by需要排序
3 使用慢查詢分析:
在my.ini中:
long_query_time=1
log-slow-queries=d:\mysql5\logs\mysqlslow.log
把超過1秒的記錄在慢查詢日誌中
可以用mysqlsla來分析之。也可以在mysqlreport中,有如
DMS 分別分析了select ,update,insert,delete,replace等所佔的百份比
4 MYISAM和INNODB的鎖定
myisam中,注意是表鎖來的,比如在多個UPDATE操作後,再SELECT時,會發現SELECT操作被鎖定了,必須等所有UPDATE操作完畢後,再能SELECT
innodb的話則不同了,用的是行鎖,不存在上面問題。
5 MYSQL的事務配置項
innodb_flush_log_at_trx_commit=1
表示事務提交時立即把事務日誌寫入磁碟,同時資料和索引也更新
innodb_flush_log_at_trx_commit=0
事務提交時,不立即把事務日誌寫入磁碟,每隔1秒寫一次
innodb_flush_log_at_trx_commit=2
事務提交時,立即寫入磁碟檔案(這裡只是寫入到核心緩衝區,但不立即重新整理到磁碟,而是每隔1秒重新整理到盤,同時更新資料和索引
explain用法
EXPLAIN tbl_name
或:
EXPLAIN [EXTENDED] SELECT select_options
前者可以得出一個表的欄位結構等等,後者主要是給出相關的一些索引資訊,而今天要講述的重點是後者。
舉例
mysql> explain select * from event;
+—-+————-+——-+——+—————+——+———+——+——+——-+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+—-+————-+——-+——+—————+——+———+——+——+——-+
| 1 | SIMPLE | event | ALL | NULL | NULL | NULL | NULL | 13 | |
+—-+————-+——-+——+—————+——+———+——+——+——-+
1 row in set (0.00 sec)
各個屬性的含義
id
select查詢的序列號
select_type
select查詢的型別,主要是區別普通查詢和聯合查詢、子查詢之類的複雜查詢。
table
輸出的行所引用的表。
type
聯合查詢所使用的型別。
type顯示的是訪問型別,是較為重要的一個指標,結果值從好到壞依次是:
system > const > eq_ref > ref > fulltext > ref_or_null > index_merge > unique_subquery > index_subquery > range > index > ALL
一般來說,得保證查詢至少達到range級別,最好能達到ref。
possible_keys
指出MySQL能使用哪個索引在該表中找到行。如果是空的,沒有相關的索引。這時要提高效能,可通過檢驗WHERE子句,看是否引用某些欄位,或者檢查欄位不是適合索引。
key
顯示MySQL實際決定使用的鍵。如果沒有索引被選擇,鍵是NULL。
key_len
顯示MySQL決定使用的鍵長度。如果鍵是NULL,長度就是NULL。文件提示特別注意這個值可以得出一個多重主鍵裡mysql實際使用了哪一部分。
ref
顯示哪個欄位或常數與key一起被使用。
rows
這個數表示mysql要遍歷多少資料才能找到,在innodb上是不準確的。
Extra
如果是Only index,這意味著資訊只用索引樹中的資訊檢索出的,這比掃描整個表要快。
如果是where used,就是使用上了where限制。
如果是impossible where 表示用不著where,一般就是沒查出來啥。
如果此資訊顯示Using filesort或者Using temporary的話會很吃力,WHERE和ORDER BY的索引經常無法兼顧,如果按照WHERE來確定索引,那麼在ORDER BY時,就必然會引起Using filesort,這就要看是先過濾再排序划算,還是先排序再過濾划算。
常見的一些名詞解釋
Using filesort
MySQL需要額外的一次傳遞,以找出如何按排序順序檢索行。
Using index
從只使用索引樹中的資訊而不需要進一步搜尋讀取實際的行來檢索表中的列資訊。
Using temporary
為了解決查詢,MySQL需要建立一個臨時表來容納結果。
ref
對於每個來自於前面的表的行組合,所有有匹配索引值的行將從這張表中讀取
ALL
完全沒有索引的情況,效能非常地差勁。
index
與ALL相同,除了只有索引樹被掃描。這通常比ALL快,因為索引檔案通常比資料檔案小。
SIMPLE
簡單SELECT(不使用UNION或子查詢)