目錄
explain命令通常用來分析低效SQL語句執行慢的原因。explain命令可以獲取MySQL執行select語句的指定計劃,包括select語句執行過程中表如何連接和連接的順序。示例:
1、id
id表示執行順序,數字越大越先執行;在數字大小相等的情況下,從上到下執行。例如在上面的例子中,最先執行的就是最下面那條id = 2的命令。
對於多表關聯的情況,一般關聯表的id是相同的,但是從上到下第一個表是作爲關聯主表的。
2、select_type
表示SELECT的類型,常見的取值包括:
- SIMPLE:簡單的select查詢,查詢中不包含子查詢和union;
- PRIMARY:查詢中包含若干複雜的子部分,最外層查詢會被標記爲PRIMARY;
- UNION:如果第二個select出現在union之後,則會被標記爲UNION;如果UNION包含在FROM子句的子查詢中,外層SELECT將被標記爲DERIVED;
- UNION RESULT:從UNION表獲取結果的SELECT;
- SUBQUERY:在SELECT或者WHERE子句中包含的子查詢;
- DERIVED:衍生,在FROM列表中包含的子查詢被標記爲DERIVED,MySQL會遞歸這些子查詢,把結果放到臨時表中。
3、table
指的是輸出結果集的表,即這一行子句是在哪個表中獲取數據。
4、type
type指的是掃描的類型。mysql5.7中type的類型多達14種,常見的如下幾種:
- all:全表掃描;
- index:按照索引的順序掃描全表,然後再回表讀數據。這種情況唯一會比all更快的地方就在於,按照索引掃描是有序的;
- range:有範圍的索引掃描,相當於有範圍的index類型;
- ref: 查找條件列使用了等號條件,並且使用了非唯一索引;
- ref_eq:掃描唯一索引的ref;
- const:掃描唯一索引,並且該唯一索引列的值爲確定的常量。此時MySQL將查詢這一部分優化成了一個常量;
- null:MySQL在優化過程中分解語句,執行時甚至不用訪問表或索引,例如從一個索引列裏選取最小值可以通過單獨索引查找完成。
5、possible_keys、key和key_len
分別表示可能會使用到的索引、實際上使用的索引,以及實際使用的索引列的長度。
6、ref
表示上述表的連接匹配條件,即哪些列或常量被用於查找索引列上的值。
7、rows
內循環的次數,可以理解爲這次查找數據所掃描的行數。
8、Extra
- Using temporary:說明使用了臨時表。MySQL的臨時表分爲in-memory和on-disk兩種,優先使用in-memory臨時表, 而當臨時表太大時,則會被轉存爲on-disk臨時表。臨時表一般用來處理比較複雜的排序、去重、分組等查詢,或表的關聯;
- Using index:索引覆蓋查詢。覆蓋索引指的是可以利用索引返回select需要的全部字段,而不必再次回表讀取數據;
- Using where:MySQL服務器會在存儲引擎返回行以後,再在服務器中而不是存儲引擎中用where進行過濾;
- Using filesort:並不是說一定是通過磁盤文件進行排序,只是說明進行了一個排序操作,區別於使用索引進行排序。這時如果數據量小會在內存中排序(以排序緩衝區爲界),如果數據量大則會在文件中排序;
- Using index for group-by:MySQL在特定場景下支持鬆散索引掃描,例如在一個分組中查詢分組的最大值和最小值;
- Using index condition:查找使用了索引,但是需要回表查詢數據,以及用WHERE其他的其他條件進行過濾;
- select tables optimized away:優化器從執行計劃中移除了該表,並以常數代之,因爲MySQL直接從內部表中讀到了這個相應的值。查詢整列索引列的min()、max()、count()會出現這種提示。
- Using union(index1, index2,index3):索引合併