1、explain是什麼?sql
簡單來說就是官方給的一個優化工具,直接在你的SQL語句前加上explain,執行整條語句,以後你就能夠根據執行結果優化你的SQL啦,廢話很少說,直接剛實例函數
一、建立測試表工具
CREATE TABLE `sql_explain_student` (
測試
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '自增ID',
優化
`name` varchar(30) DEFAULT NULL COMMENT '學生名字',
spa
`age` int(11) DEFAULT NULL COMMENT '學生年齡',
指針
`sex` tinyint(4) DEFAULT NULL COMMENT '性別',
code
`class` int(11) DEFAULT NULL COMMENT '學生班級',
blog
PRIMARY KEY (`id`)
排序
) ENGINE=InnoDB DEFAULT CHARSET=utf8
數據本身隨意建
二、來個簡單的測試語句
select * from sql_explain_student;
explain
select * from sql_explain_student;
結果:
以後咱們就能夠根據結果分析咱們的語句的優劣,及如何優化了(先看看看這個表裏的變量都是什麼意思,,好吧~)
table:顯示這一行的數據是關於哪張表的
type:這是重要的列,顯示鏈接使用了何種類型。從最好到最差的鏈接類型爲const、eq_reg、ref、range、index和ALL
type顯示的是訪問類型,是較爲重要的一個指標,結果值從好到壞依次是: system>const>eq_ref>ref>fulltext>ref_or_null>index_merge>unique_subquery>index_subquery>range>index>ALL
通常來講,得保證查詢至少達到range級別,最好能達到ref。
possible_keys:顯示可能應用在這張表中的索引。若是爲空,沒有可能的索引。能夠爲相關的域從WHERE語句中選擇一個合適的語句
key: 實際使用的索引。若是爲NULL,則沒有使用索引。不多的狀況下,MYSQL會選擇優化不足的索引。這種狀況下,能夠在SELECT語句中使用USE INDEX(indexname)來強制使用一個索引或者用IGNORE INDEX(indexname)來強制MYSQL忽略索引
key_len:使用的索引的長度。在不損失精確性的狀況下,長度越短越好
ref:顯示索引的哪一列被使用了,若是可能的話,是一個常數
rows:MYSQL認爲必須檢查的用來返回請求數據的行數
Extra:關於MYSQL如何解析查詢的額外信息。壞的例子是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:這個鏈接類型對於前面的每個記錄聯合進行徹底掃描,這通常比較糟糕,應該儘可能避免
id | SELECT識別符。這是SELECT的查詢序列號 |
---|---|
select_type | SELECT類型,能夠爲如下任何一種: SIMPLE:簡單SELECT(不使用UNION或子查詢) PRIMARY:最外面的SELECT UNION:UNION中的第二個或後面的SELECT語句 DEPENDENT UNION:UNION中的第二個或後面的SELECT語句,取決於外面的查詢 UNION RESULT:UNION 的結果SUBQUERY:子查詢中的第一個SELECT DEPENDENT SUBQUERY:子查詢中的第一個SELECT,取決於外面的查詢 DERIVED:導出表的SELECT(FROM子句的子查詢) |
table | 輸出的行所引用的表 |
type | 聯接類型。下面給出各類聯接類型,按照從最佳類型到最壞類型進行排序: system:表僅有一行(=系統表)。這是const聯接類型的一個特例。 const:表最多有一個匹配行,它將在查詢開始時被讀取。由於僅有一行,在這行的列值可被優化器剩餘部分認爲是常數。const表很快,由於它們只讀取一次! eqref:對於每一個來自於前面的表的行組合,從該表中讀取一行。這多是最好的聯接類型,除了const類型。 ref:對於每一個來自於前面的表的行組合,全部有匹配索引值的行將從這張表中讀取。 refornull:該聯接類型如同ref,可是添加了MySQL能夠專門搜索包含NULL值的行。indexmerge:該聯接類型表示使用了索引合併優化方法。 uniquesubquery:該類型替換了下面形式的IN子查詢的ref: value IN (SELECT primarykey FROM singletable WHERE someexpr) uniquesubquery是一個索引查找函數,能夠徹底替換子查詢,效率更高。 indexsubquery:該聯接類型相似於uniquesubquery。能夠替換IN子查詢,但只適合下列形式的子查詢中的非惟一索引: value IN (SELECT keycolumn FROM singletable WHERE someexpr) range:只檢索給定範圍的行,使用一個索引來選擇行。 index:該聯接類型與ALL相同,除了只有索引樹被掃描。這一般比ALL快,由於索引文件一般比數據文件小。 ALL:對於每一個來自於先前的表的行組合,進行完整的表掃描。 |
possible_keys | 指出MySQL能使用哪一個索引在該表中找到行 |
key | 顯示MySQL實際決定使用的鍵(索引)。若是沒有選擇索引,鍵是NULL。 |
key_len | 顯示MySQL決定使用的鍵長度。若是鍵是NULL,則長度爲NULL。 |
ref | 顯示使用哪一個列或常數與key一塊兒從表中選擇行。 |
rows | 顯示MySQL認爲它執行查詢時必須檢查的行數。多行之間的數據相乘能夠估算要處理的行數。 |
filtered | 顯示了經過條件過濾出的行數的百分比估計值。 |
Extra | 該列包含MySQL解決查詢的詳細信息 Distinct:MySQL發現第1個匹配行後,中止爲當前的行組合搜索更多的行。 Not exists:MySQL可以對查詢進行LEFT JOIN優化,發現1個匹配LEFT JOIN標準的行後,再也不爲前面的的行組合在該表內檢查更多的行。 range checked for each record (index map: #):MySQL沒有發現好的可使用的索引,但發現若是來自前面的表的列值已知,可能部分索引可使用。 Using filesort:MySQL須要額外的一次傳遞,以找出如何按排序順序檢索行。 Using index:從只使用索引樹中的信息而不須要進一步搜索讀取實際的行來檢索表中的列信息。 Using temporary:爲了解決查詢,MySQL須要建立一個臨時表來容納結果。 Using where:WHERE 子句用於限制哪個行匹配下一個表或發送到客戶。 Using sortunion(...), Using union(...), Using intersect(...):這些函數說明如何爲indexmerge聯接類型合併索引掃描。 Using index for group-by:相似於訪問表的Using index方式,Using index for group-by表示MySQL發現了一個索引,能夠用來查 詢GROUP BY或DISTINCT查詢的全部列,而不要額外搜索硬盤訪問實際的表。 |