1. explain作用
使用explain可以展示出sql語句的執行計劃,再根據sql的執行計劃去判斷這條sql有哪些點可以進行優化,從而讓sql的效率達到最大化。
2. 執行計劃各列含義
(1)id:id列是select的序列號,這個sql執行過程中會執行幾次select就有幾個id,并且id是按照select出現的順序增長的,id列的值越大優先級越高,id相同則是按照執行計劃列從上往下執行。
(2)select_type:該列表示查詢的類型,是簡單查詢還是復雜查詢。
- simple:不包含子查詢和union的簡單查詢。
- primary:包含子查詢的復雜查詢中最外層的查詢。
- subquery:包含子查詢的復雜查詢中的子查詢。
從下面sql執行計劃中可以看出外層查詢user表的類型為PRIMARY,where后面的子查詢roles表類型為SUBQUERY。
- derived:衍生查詢,查詢臨時表中的數據。
- union:在union中的第二個和隨后的查詢。
- union result:表示合并的結果,最后的extra列中的Using temporary表示會創建一個臨時表來存儲合并結果。
從下面sql的執行計劃可以看出,第一條的類型為PRIMARY,就是復雜查詢中的最外層的查詢。
第二條的類型為DERIVED,即在from子句的子查詢中的結果放到一個臨時表中,也就是對r1表的查詢結果會衍生出一個臨時表,所以對r1表的查詢類型為DERIVED。第三條是對r2表的查詢,由于是在union的后面,所以查詢類型為UNION。第四條則是對2,3條查詢的合并結果當作最終的子查詢結果并存放在衍生出來的臨時表中。
(3)table:該列表示當前行訪問的是哪張表,通常是表名或者該表的別名。
(4)partitions:該列表示查詢將匹配記錄的分區。 對于非分區表,該值為 NULL。
(5)type:該列表示關聯類型或訪問類型。該列的值決定了這條sql的查詢性能,從最優到最差分別為:system > const > eq_ref > ref > range > index > all。
- system :表示整個表中只有一條記錄,這種情況幾乎不會出現。
- const :表示整個表中通過該字段查找只有唯一的一條記錄,一般會出現在主鍵索引或者唯一索引的字段。
- eq_ref :一般是關聯查詢的時候,主表用于關聯的索引字段在被關聯的副表中有且只有唯一一條記錄。被關聯的副表字段一般為主鍵或者唯一索引字段。
- ref :一般是使用普通索引進行查詢,查詢的結果會存在多個符合條件的記錄。
- range :通常出現在范圍查詢中,比如in、between、大于、小于等。使用索引來檢索給定范圍的行。
- index :從創建的索引文件中掃描全部索引數據,通常比ALL快一點。
- all:在磁盤從頭到尾的掃描全表數據來找到所需要的數據,查詢速率最差。
(6)possible_keys:該列表示在查詢中可能用到的索引,僅僅只是可能,列出來的索引并不一定真正的使用到。如果該列為NULL,則表示沒有相關索引。
(7)key:該列表示真正使用到的索引。
(8)key_len:該列表示sql查詢語句中索引使用到的字節數,這個字節數并不是實際的長度,而是通過計算查詢中使用到的索引中的長度得出來的,顯示的是索引字段最大的可能長度。key_len是越小越好。
(9)ref:該列表示在key列記錄的實際使用的索引中,表查找值時使用到的列或常量。常見的有const、字段名。
(10)rows:該列表示估算的要掃描的行數,注意這個并不是實際結果集的行數。
(11)Extra:該列表示是sql查詢的額外信息,主要有以下幾種情況:Using index、Using where、Using temporary、Using filesort、Impossible where、Select tables optimized away。
- Using index:表示查詢的列被索引覆蓋,索引被正確的使用,想要查詢的信息在索引里面可以找到,不用再回表查詢,這個是查詢性能比較高的體現。
- Using where:表示查詢的列并沒有被索引覆蓋,where條件后面使用的是非索引的前導列,它僅僅是使用了where條件而已。
- Using temporary:表示使用了臨時表存儲中間的結果,一般在進行合并查詢的時候會使用臨時表。
- Using filesort:表示文件排序,說明Mysql對數據使用了外部的索引進行排序,并沒有使用表中的索引進行排序。
- Impossible where:表示where后的條件一直為false。
- Select tables optimized away:表示使用某些聚合函數(比如 max、min)來訪問存在索引的某個字段時。