MySQL 之 Explain 輸出分析

科技伍小黑 發佈 2020-01-28T17:44:18+00:00

我們來一一看下Explain輸出的欄位內容id, select_type, table, partitions, type, possible_keys, key, key_len, ref, rows,filtered,extra列名含義id查詢語句的標識select_type

背景

前面的文章寫過 MySQL 的事務和鎖,這篇文章我們來聊聊 MySQL 的 Explain,估計大家在工作或者面試中多多少少都會接觸過這個。可能工作中實際使用的不多,但是不論的自己學習還是面試,都需要掌握的。Explain 可以使用在 SELECT, DELETE, INSERT, REPLACE, and UPDATE 語句中,執行的結果會在每一行顯示用到的每一個表的詳細信息。簡單語句可能結果就只有一行,但是複雜的查詢語句會有很多行數據。

Explain 的使用

在 SQL 語句前面加上 explain ,如: EXPLAIN SELECT * FROM a;

舉個例子


CREATE TABLE `a` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `uid` int(10) unsigned DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `idx_uid` (`uid`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;


採用上面的語句 EXPLAIN SELECT * FROM a; ,效果如下

通過圖片我們可以看到執行過後會輸出 12 個欄位,那麼每個欄位是什麼意思呢?我們來一一看下

Explain 輸出的欄位內容

id, select_type, table, partitions, type, possible_keys, key, key_len, ref, rows,filtered,extra

列名含義id查詢語句的標識select_type查詢的類型table當前行所查的表partitions匹配的分區type訪問類型possible_keys查詢可能用到的索引keymysql 決定採用的索引來優化查詢key_len索引 key 的長度ref顯示了之前的表在key列記錄的索引中查找值所用的列或常量rows查詢掃描的行數,預估值,不一定準確filtered查詢的表行占表的百分比extra額外的查詢輔助信息

常用欄位詳細介紹

  1. id: 是用來順序標識整個查詢中 select 語句的,在嵌套查詢中id越大的語句越先執行
  2. select_type:simple: 簡單的SELECT(不使用UNION或子查詢)primary: 最外面的SELECTunion: UNION中的第二個或更高的SELECT語句dependent union: UNION中的第二個或更高的SELECT語句,取決於外部查詢union result: UNION的結果subquery: 在子查詢中首先選擇SELECTdependent subquery: 子查詢中的第一個SELECT,取決於外部查詢derived: 派生表——該臨時表是從子查詢派生出來的,位於from中的子查詢uncacheable subquery: 無法緩存結果的子查詢,必須為外部查詢的每一行重新計算uncacheable union: 在UNION中的第二個或更晚的選擇屬於不可緩存的子查詢
  3. table: 每一行引用的表名
  4. type: 從上到下效果依次降低system: const 的一種特例,表中只有一行數據const: 當確定最多只會有一行匹配的時候,MySQL優化器會在查詢前讀取它而且只讀取一次,因此非常快。使用主鍵查詢往往就是 const 級別的,非常高效eq_ref: 最多只返回一條符合條件的記錄,通過使用在兩個表有關聯欄位的時候ref: 通過普通索引查詢匹配的很多行時的類型fulltext: 全文索引ref_or_null: 跟 ref 類似的效果,不過多一個列不能 null 的條件index_merge: 此連接類型表示使用了索引合併優化。在這種情況下,輸出行中的 key 列包含使用的索引列表,key_len包含所用索引的最長 key 部分列表unique_subquery: 在使用 in 查詢的情況下會取代 eq_refrange: 範圍掃描,一個有限制的索引掃描。key 列顯示使用了哪個索引。當使用=、 <>、>、>=、<、<=、IS NULL、<=>、BETWEEN 或者 IN 操作符,用常量比較關鍵字列時,可以使用 rangeindex: 類似全表掃描,只是掃描表的時候按照索引次序進行而不是行。主要優點就是避免了排序, 但是開銷仍然非常大。如在Extra列看到Using index,說明正在使用覆蓋索引,只掃描索引的數據,它比按索引次序全表掃描的開銷要小很多ALL: 全表掃描
  5. possible_key: MySQL 可能採用的索引,但是並不一定使用
  6. key: MySQL 正真使用的索引名稱
  7. rows: 預估的掃描行數,只能參考不準確
  8. extra: 該列包含了很多額外的信息,包括是否文件排序,是否有臨時表等,很多時候這個欄位很有用能提供很多信息

小結

今天簡單的給大家介紹了一些 Explain 的輸出信息,很多時候我們可能在平時很少接觸,但是很多時候我們還是要掌握的。有些東西該記還得記,該背還得背,畢竟這個社會就是比的誰知道的多。

關鍵字: