本萌最近被一則新聞深受鼓舞,西工大硬核「女學神」白雨桐,獲6所世界頂級大學博士錄取通知書mysql
貨真價值的才貌雙全,別人家的孩子sql
高考失利與心儀的專業失之交臂,選擇了軟件工程這門本身徹底不懂的專業.即使所有歸零,也要證實本身,連續3年專業綜合排名第一,各類獲獎經歷寫滿了5頁PPT。成功始於不斷的努力和拼搏,在學習和實踐中不斷提高本身。緩存
【技本功】願作你成功路上的基石,趕忙來接收今日份的精神投食~oop
1、解讀type學習
執行計劃的type表示訪問數據類型,有不少種訪問類型。優化
一、system
表示這一步只返回一行數據,若是這一步的執行對象是一個驅動表或者主表,那麼被驅動表或者子查詢只是被訪問一次。spa
二、constserver
表示這個執行步驟最多隻返回一行數據。const一般出如今對主鍵或惟一索引的等值查詢中,例如對錶t主鍵id的查詢:對象
三、eq_ref排序
eq_ref類型通常意味着在表關聯時,被關聯表上的關聯列走的是主鍵或者惟一索引。例如,表jiang關聯lock_test表,關聯列分別是兩張表的主鍵列 :
上面SQL執行時,jiang表是驅動表,lock_test是被驅動表,被驅動表的關聯列是主鍵id,type類型爲eq_ref。
因此,對於eq_ref類型來講有一個重要的特色就是:這一步涉及到的表是被驅動表;這一步中使用到惟一索引或主鍵。除了system和const以外,這是效果最好的關聯類型。
四、ref
與上面相反,若是執行計劃的某一步的type是ref的話,表示這一步的關聯列是非惟一索引。例如,用表jiang的主鍵id列關聯表lock_test的num列,num列上創建了普通索引:
上面SQL執行時,表jiang是驅動表,lock_test是被驅動表,被驅動表上走的是非惟一索引,type類型爲ref。
因此ref的特色是:表示這一步訪問數據使用的索引是非惟一索引。
五、Ref_or_null
例如執行下面語句:
表示走了索引(num列上有索引),可是也訪問了空值。
六、index_merge
表示索引合併,通常對多個二級索引列作or操做時就會發生索引合併。
例如執行下列語句:
mysql> explain select * from lock_test where id=3 or num=4;
id爲主鍵,num列上建有普通索引,語句執行時,會經過兩個單列索引來處理or操做。
七、unique_subquery
表示惟一子查詢。例若有以下語句執行時:
value in(select primary_key from single_table where ...)
對於in子句來講,當in子句裏的子查詢返回的是某一個表的主鍵時,type顯示爲unique subquery。
八、index_subquery
當有以下語句執行時:
value in(select key_column from single_table where ...)
與上面的類似,表示對於in子句來講,當in子句裏的子查詢返回的是某一個表的二級索引列(非主鍵列)時,type顯示爲index_subquery。
九、range:
在有索引的列上取一部分數據。常見於在索引列上執行between and操做。
十、index:
索引全掃描,通常發生在覆蓋索引的時候,也就是對有索引列發生一次全掃描。
十一、all:
沒有索引的全表掃描。
一個特例:
Explain select * from stu limit 1,1;
2、解讀extra
一、using where:
通常有兩層意思:
表示經過索引訪問時,須要再回表訪問所需的數據;
過濾條件發生在server層而不是存儲引擎層;
若是執行計劃中顯示走了索引,可是rows值很高,extra顯示爲using where,那麼執行效果就不會很好。由於索引訪問的成本主要在回表上,這時能夠採用覆蓋索引來優化。
經過覆蓋索引也能將過濾條件下壓,在存儲引擎層執行過濾操做,這樣效果是最好的。
因此,覆蓋索引是解決using where的最有效的手段。
二、using index condition
表示將過濾下壓到存儲層執行,防止server層過濾過多數據
若是extra中出現了using index condition,說明對訪問表數據進行了優化。
三、using temporary
表示語句執行過程當中使用到了臨時表。如下子句的出現可能會使用到臨時表:
order by
group by
distinct
union等
數據不能直接返回給用戶,就須要緩存,數據就以臨時表緩存在用戶工做空間。注意,可能會出現磁盤臨時表,須要關注須要緩存的數據的rows。
可使用索引消除上面的四個操做對應的臨時表。
四、using sort_union(indexs)
好比當執行下面語句:
Sname和sphone列上都有索引,這時執行計劃的extra項就會顯示using sort_union(i_sname,i_spone),表示索引合併。常伴隨着index_merge。
五、using MRR:
通常經過二級索引訪問表數據的過程是:先訪問二級索引列,找到對應的二級索引數據後就獲得對應的主鍵值,而後拿着這個主鍵值再去訪問表,取出行數據。這樣取出的數據是按照二級索引排序的。
MRR表示:經過二級索引獲得對應的主鍵值後,不直接訪問表而是先存儲起來,在獲得全部的主鍵值後,對主鍵值進行排序,而後再訪問表。這樣能夠大幅減低對錶的訪問次數,至少實現了順序訪問表。
MRR的一個優勢就是提高索引訪問表的效率,也就是下降了回表的成本。可是有一個比較大的問題:取出來的數據就不按照二級索引排序了。
六、using join buffer(Block Nested Loop)
BNL主要發生在兩個表關聯時,被關聯的表上沒有索引。
BNL表示這樣的意思:A關聯B,A的關聯列上有索引而B的沒有。這時就會從A表中取10行數據拿出來放到用戶的join buffer空間中,而後再取B上的數據和join buffer中A的關聯列進行關聯,這時只須要對B表訪問一次,也就是B表發生一次全表掃描。
若是join buffer中的10行數據關聯完後,就再取10行數據繼續和B表關聯,一直到A表的全部數據都關聯完爲止。
從上面能夠看出來,這種方式大概效率會提升約90%。
七、using join buffer(Batched Key Access)
通常出現BKA的狀況是:表關聯時,被驅動表上有索引,可是驅動表返回的行數太多。
當出現上述狀況時,就會將驅動表的返回結果集放到用戶工做空間的join buffer中,而後取結果集的一條記錄去關聯被驅動表的索引關聯列。獲得相應的主鍵列後並不立刻經過這個主鍵列去被被驅動表中取數據,而是先存放到工做空間中。等到結果集中的全部數據都關聯完了,對工做空間中的全部經過關聯獲得主鍵列進行排序,而後統一訪問被驅動表,從中取數據。這樣的好處就是大大下降了訪問的次數。
從上面能夠看出:BKA用到了MRR技術;BKA適合驅動表返回行數較多、被驅動表訪問時走的是索引的狀況。
這個功能能夠打開或者關閉:
Set optimizer_switch=’mrr=on,batched_key_access=on’;
八、using index for group by
表示經過複合索引完成group by,不用回表。
例如複合索引(a,b),執行語句:select a from tb group by b;時就會出現using index for group by。
九、using index
表示實現了覆蓋索引掃描;也就是須要訪問的數據都在索引中,不須要回表。在通常狀況下,減小沒必要要的數據訪問可以提高效率。
例如對錶lock_test取num列上的數據,num列上創建普通索引:
十、using filesort
說明有排序行爲,可是不必定是磁盤排序。
十一、materialize scan對物化表的全掃描,由於物化表就是一個臨時表,表上沒有索引。