前言
explain命令是查看查詢優化器如何決定執行查詢的主要方法。
這個功能有局限性,并不總會說出真相,但它的輸出是可以獲取的最好信息,值得花時間去了解,因為可以學習到查詢是如何執行的。
調用EXPLAIN
在select之前添加explain,mysql會在查詢上設置一個標記,當執行查詢計劃時,這個標記會使其返回關于執行計劃中每一步的信息,而不是執行它。
它會返回一行或多行信息,顯示出執行計劃中的每一部分和執行次序。
這是一個簡單的explain效果:

在查詢中每個表在輸出只有一行,如果查詢是兩個表的聯接,那么輸出中將有兩行。
別名表單算為一個表,因此,如果把一個表與自己聯接,輸出中也會有兩行。
“表”的意義在這里相當廣,可以是一個子查詢,一個union結果等。
同時 explain有兩個變種
EXPLAIN EXTENDED會告訴服務器“逆向編譯” 執行計劃為一個select語句。
可以通過緊接其后運行show warnings看到這個生成的語句,這個語句直接來自執行計劃,而不是原SQL語句,到這點上已經變成一個數據結構。
大部分場景下,它都與原語句不相同,你可以檢測查詢偶花旗到底是如何轉化語句的。
EXPLAIN EXTENDED在mysql 5.0 以上版本中可用,在5.1中增加了一個filtered列。
EXPLAIN PARTITIONS會顯示查詢將訪問的分區,如果查詢是基于分區表的話。
在mysql 5.1以上的版本中會存在。
EXPLAIN限制:
· explain根本不會告訴你觸發器、存儲過程或UDF會如何影響查詢
· 不支持存儲過程,盡管可以手動抽取查詢并單獨地對其進行explain操作
· 它并不會告訴你mysql在執行計劃中所做的特定優化
· 它并不會顯示關于查詢的執行計劃的所有信息
· 它并不區分具有相同名字的事物,例如,它對內存排列和臨時文件都使用“filesort”,并且對于磁盤上和內存中的臨時表都顯示“Using temporary”
· 可能會產生誤導,比如,它會對一個有著很小limit的查詢顯示全索引掃描(mysql 5.1的explain關于檢查的行數會顯示更精準的信息,但早期版本并不考慮limit)
重寫非SELECT查詢
mysql explain只能解釋select查詢,并不會對存儲程序調用和insert、update、delete或其他語句做解釋。然而,你可以重寫某些非select查詢以利用explain。為了達到這個目的,只需要將該語句轉化成一個等價的訪問所有相同列的select,任何體積的列都必須在select列表,關聯子句,或者where子句中。
新聞熱點
疑難解答