本文是關於在學習《高性能 Mysql》附錄 D 中關於 Explain 如何獲取執行計劃信息相關總結。MySQL 提供了一個 EXPLAIN 命令,它能夠對 SELECT 語句進行分析,獲取優化器對當前查詢的執行計劃,以供開發人員針對相關 SQL 進行優化。在 SELECT 語句前加上 Explain 就能夠查看到相關信息, 例如:mysql
EXPLAIN SELECT * from user_info WHERE id < 300;
複製代碼
SELECT 查詢的標識符. 每一個 SELECT 都會自動分配一個惟一的標識符.sql
select_type 表示了查詢的類型, 它的經常使用取值有:segmentfault
查詢的是哪一個表,mysql 查詢優化器執行的關聯順序並不和咱們寫 SQL 時關聯的順序一致,下面咱們講一下 Mysql 是如何對關聯查詢做優化的:性能優化
type 字段比較重要, 它提供了判斷查詢是否高效的重要依據依據. 經過 type 字段, 咱們判斷這次查詢是全表掃描仍是索引掃描等,type 類型的性能比較,一般來講, 不一樣的 type 類型的性能關係以下:bash
ALL < index < range < ref < eq_ref < const < system < NULL服務器
# 由於表中backend_user是主鍵,因此子查詢裏最多能夠選出一條數據,因此最外層查詢的type是system,裏層查詢的type是const
explain select * from (select * from backend_user where id = 1) a;
複製代碼
# 雖然是都是範圍查詢,其實第二個查詢時多個等值條件查詢
# 對於第一個查詢,mysql 沒法再使用該列後面的其它查詢索引了,而第二個則能夠繼續使用索引
select id from actor where id > 45 and class_id = 3;
select id from actor where id in (44, 47, 48) and class_id = 3;
複製代碼
這次查詢中可能選用的索引,這些索引列是根據查詢的列以及比較操做符來判斷的,可能在後續的真實查詢中沒有用到也有可能性能
這次查詢中確切使用到的索引,若是在 possible_keys 中沒有出現而在 key 中出現,說明優化器可能出於另外緣由好比選擇覆蓋索引,因此 possiable_keys 揭示了哪個索引有助於高效進行查找,而 key 顯示了採用哪個索引能夠最小化查詢成本。學習
表示查詢優化器使用了索引的字節數. 這個字段能夠評估組合索引是否徹底被使用, 或只有最左部分字段被使用到,好比咱們建了一個組合索引(col1, col2),那麼以下兩條查詢雖然用到的都是這個組合索引,可是對應的key_len的只是不同的。key_len 顯示了在索引字段中可能的最大長度,而不是數據使用的實際字節數優化
select * from table1 where col1 = 1;
select * from table1 where col1 = 1 and col2 = 2;
複製代碼
這一列顯示了以前的表在 key 列記錄的索引中查找值所用的列或者常量ui
rows 也是一個重要的字段. MySQL 查詢優化器根據統計信息, 估算 SQL 要查找到結果集須要掃描讀取的數據行數。這個值很是直觀顯示 SQL 的效率好壞, 原則上 rows 越少越好。
filtered 是在 MYSQL 5.1 中加進來的,在使用 EXPLAIN EXTENDED 時出現,表示此查詢條件所過濾的數據的百分比,將 rows 除以 filtered 能夠估算出整個表數據行數。
EXplain 中的不少額外的信息會在 Extra 字段顯示, 常見的有如下幾種內容:
當 Extra 中有 Using filesort 時, 表示 MySQL 需額外的排序操做, 不能經過索引順序達到排序效果. 通常有 Using filesort, 都建議優化去掉, 由於這樣的查詢 CPU 資源消耗大。 可是 Explain 不會告訴你 Mysql 將使用文件排序仍是內存排序:
-- 好比咱們創建索引爲:KEY `user_product_detail_index` (`user_id`, `product_name`, `productor`),那麼以下兩個查詢
EXPLAIN SELECT * FROM order_info ORDER BY product_name; -- Using filesort,不能經過索引進行排序,須要優化
EXPLAIN SELECT * FROM order_info ORDER BY user_id, product_name;-- 無 Using filesort,經過索引進行排序,優化成功
複製代碼
"覆蓋索引掃描", 表示查詢在索引樹中就可查找所需數據, 不用掃描表數據文件, 每每說明性能不錯
這意味着 Mysql 服務器在存儲引擎檢索行後再進行過濾,通常出現 「Using where」 會受益於不一樣的索引
查詢有使用臨時表, 通常出現於排序, 分組和多表 join 的狀況, 臨時表多是內存臨時表或者文件臨時表
在 Mysql 5.1 版本中引入了 EXPLAIN PARTITIONS 能夠顯示查詢將訪問的分區狀況