map语法获取index_MySQL SQL语法优化——使用Explain查看执行计划
夜深,最近在寫SQL優化的一些文章,看到私聊中,有很多人在問如何判斷是否需要優化或者是如何查看MySQL執行計劃,本文簡要介紹一下MySQL EXPLAIN命令。
EXPLAIN命令是查看優化器如何決定執行查詢的主要方法。通常,我們查看執行計劃獲取以下信息:
- SQL如何使用索引
- 聯接查詢的執行順序
- 查詢掃描的數據行數
- 哪些索引可以使用
- 哪些索引被實際使用
MySQL Explain語法
如下
執行計劃包含的信息
ID 說明
表示執行SELECT語句的順序,ID相同時,執行順序由上至下。如果是子查詢,ID的序號會遞增,ID越大優先級越高,越優先被執行。
SELECT_TYPE說明
- SIMPLE:簡單查詢,即不包含子查詢或是UNION操作的查詢。
- PRIMARY:最外層查詢,即查詢中包含任何子查詢,則最外層的查詢則被標記為PRIMARY。
- SUBQUERY:映射為子查詢,即在SELECT 或 WHERE列表中包含了子查詢 。
- DEPENDENT SUBQUERY:依賴外部結果的子查詢。
- DERIVED:子查詢,即出現在FROM子句中的子查詢。
- UNION:聯合,若第二個SELECT出現在UNION之后,則被標記為UNION。若UNION包含在FROM子句的子查詢中,外層SELECT將被標記為DERIVED。
- UNION RESULT:使用聯合的結果,即UNION產生的結果集。
TABLE 說明
指的就是當前執行的表,即輸出數據行所在的表的名稱。由ID為M,N查詢union產生的結果集,或者是由ID為N的查詢產生的結果。
TYPE 說明
- ALL:全數據表掃描 ,遍歷全表以找到匹配的行,效率最差。
- INDEX:全索引表掃描,INDEX與ALL區別為index類型只遍歷索引樹。
- RANGE:對索引列進行范圍查找,只檢索給定范圍的行,使用一個索引來選擇行,常見于BETWEEN、>、
- INDEX_MERGE:合并索引,使用多個單列索引搜索。
- REF:使用非唯一索引掃描或者唯一索引的前綴掃描,返回匹配某個單獨值的數據行,然而他可能會找到多個符合條件的行,所以它應該屬于查找和掃描的混合體 。
- EQ_REF:唯一性索引掃描,對于每個索引鍵,表中只有一條數據與之匹配。常見于主鍵 或 唯一索引掃描。
- CONST:表中有且只有一個匹配的行時使用。因為僅有一行,在這行的列值可被優化器剩余部分認為是常數,如對主鍵或是唯一索引的查詢,效率最高的聯接方式。
- SYSTEM:SYSTEM是CONST類型的特例,即當查詢的表只有一行的情況下(等于系統表)。
- NULL: MySQL在優化過程中分解語句,執行時甚至不用訪問表或索引,例如從一個索引列里選取最小值可以通過單獨索引查找完成。
性能排序如下:
一般來說,得保證查詢至少達到RANGE級別,最好能達到REF。
POSSIBLE_KEYS 說明
可能使用的索引,指出MySQL能使用哪些索引來優化查詢,查詢涉及到的字段上若存在索引,則該索引將被列出,但不一定被查詢使用。
KEY 說明
KEY 列顯示MySQL實際決定使用的索引,如果沒有可用的索引,則顯示為NULL。如查詢使用了覆蓋索引,則該索引僅出現在Key列中。要想強制MySQL使用或忽視POSSIBLE_KEYS 列中的索引,在查詢中使用FORCE INDEX、USE INDEX或者IGNORE INDEX。
KEY_LEN 說明
表示索引中使用的字節數,可通過該列計算查詢中使用的索引的長度,KEY_LEN 顯示的值為索引字段的最大可能長度,理論上長度越短越好,但并非實際使用長度,即KEY_LEN 是根據表定義計算而得,而不是通過表內檢索出的。
REF 說明
表示上述表的連接匹配條件,即表示哪些列或常量被用于查找索引列上的值。
ROWS 說明
表示MySQL根據表統計信息及索引選用情況,估算的找到所需的數據所需要讀取的行數,ROWS值的大小是個統計抽樣結果,并不完全準確。
Extra 說明
不適合在其他列中顯示,但又很重要的額外信息,有以下幾種情況:
- using index:使用了覆蓋索引(Covering Index)進行查詢,以避免訪問表。
- using where:MySQL將在存儲引擎檢索行后再進行過濾。許多WHERE條件里涉及索引中的列,當它讀取索引時,就能被存儲引擎檢驗,因此不是所有帶WHERE子句的查詢都會顯示"using where"。
- using temporary:MySQL需要使用臨時表來存儲結果集,常見于排序、子查詢和分組查詢。
- using filesort:MySQL中無法利用索引完成的排序操作稱為文件排序。MySQL有兩種文件排序方式,都可以在內存或者磁盤上完成, 通常會出現在ORDER BY或GROUP BY查詢中。
- not exists:使用Not Exists來優化查詢。
- select tables optimized away:直接通過索引來獲取數據,不用訪問表。
- Using join buffer:表示在獲取連接條件時沒有使用索引,并且需要連接緩沖區來存儲中間結果。如果出現了這個值,應該注意,根據查詢的具體情況可能需要添加索引來改進性能。
引發索引失效,導致全表掃描的原因有:
- 索引列進行計算、函數、類型轉換等操作。
- 索引列使用不等于,如!= 或<>。
- 索引列使用 IS NULL ,IS NOT NULL。
- 模糊查詢LIKE 以通配符開頭如,%ab。
- 索引列使用使用 OR 來連接條件。
- 索引列使用IN 和 NOT IN 。
- 隱式轉換,類型錯誤,如字段NUM類型為varchar,WHERE條件用number,NUM = 1。
- WHERE子句和ORDER BY使用相同的索引,并且ORDER BY的順序和索引順序相同,并且ORDER BY的字段都是升序或者降序,否則不會使用索引。
- 復合索引不符合最佳左前綴原則或存在斷點。
- 如果MYSQL評估使用索引比全表掃描更慢,則不使用索引。
索引失效優化技巧
可閱讀:日拱一卒,SQL語法優化方法及實例詳解
SQL 執行順序
可閱讀:SQL查詢語句的執行順序解析
總結
以上是生活随笔為你收集整理的map语法获取index_MySQL SQL语法优化——使用Explain查看执行计划的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 内存时序揭秘:这四个参数决定性能
- 下一篇: 内存VS CPU:速度、稳定性、兼容性全