天天看點

實戰講解MySQL的expain執行計劃,面試官當場要了我(中)

1.4.6 index_merge

此聯接類型訓示使用索引合并優化。在這種情況下,輸出行中的鍵列包含使用的索引清單,而key_len包含使用的索引的最長鍵部分的清單。

1.4.7 ref_or_null

這種連接配接類型類似于ref,但是MySQL會額外搜尋包含NULL值的行。此聯接類型優化最常用于解析子查詢。在以下示例中,MySQL可以使用ref_or_null連接配接來處理ref_table:

SELECT * FROM ref_table
  WHERE key_column=expr OR key_column IS NULL;      

1.4.8 fulltext

使用FULLTEXT索引執行連接配接。

1.4.9 ref

對于先前表中的每個行組合,将從該表中讀取具有比對索引值的所有行。

如果連接配接僅使用鍵的最左字首,或者如果該鍵不是PRIMARY KEY(主鍵)或UNIQUE(唯一)索引(即如果連接配接無法根據鍵值選擇單行),則會使用ref。

如果使用的鍵僅比對幾行,則這是一種很好的聯接類型。

ref可以用于使用= or <=> 運算符進行比較的索引列。在以下示例中,MySQL可以使用ref聯接來處理ref_table:

SELECT * FROM ref_table WHERE key_column=expr;

SELECT * FROM ref_table,other_table
  WHERE ref_table.key_column=other_table.column;

SELECT * FROM ref_table,other_table
  WHERE ref_table.key_column_part1=other_table.column
  AND ref_table.key_column_part2=1;      

1.4.10 eq_ref

對于先前表中的每行組合,從此表中讀取一行。除了system和const類型,這是最好的連接配接類型。

當連接配接使用索引的所有部分并且索引是PRIMARY KEY或UNIQUE NOT NULL索引時,将使用它。

類似ref,差別在于所用索引是唯一索引,對于每個索引鍵值,表中有一條記錄比對;

簡單來說就是多表連接配接使用primary key或者unique index作為關聯條件。

eq_ref可用于使用=運算符進行比較的索引列。比較值可以是常量,也可以是使用在此表之前讀取的表中列的表達式。在以下示例中,MySQL可以使用eq_ref連接配接來處理ref_table:

SELECT * FROM ref_table,other_table
  WHERE ref_table.key_column=other_table.column;

SELECT * FROM ref_table,other_table
  WHERE ref_table.key_column_part1=other_table.column
  AND ref_table.key_column_part2=1;      

1.4.11 const

表最多有一個比對行,該行在查詢開始時讀取。因為隻有一行,是以優化器的其餘部分可以将這一行中列的值視為常量。 const表非常快,因為它們僅讀取一次。

當将PRIMARY KEY或UNIQUE索引的所有部分與常量值進行比較時,将使用const。在以下查詢中,tbl_name可以用作const表:

SELECT * FROM tbl_name WHERE primary_key=1;

SELECT * FROM tbl_name
  WHERE primary_key_part1=1 AND primary_key_part2=2;      

1.4.12 system

該表隻有一行(系統表)。這是const 連接配接類型的特例。

type null,MySQL不用通路資料庫直接得到結果。

1.5 possible_keys

此次查詢中可能選用的索引

1.6 key

此次查詢中确切使用到的索引

1.7 ref

哪個字段或常數與 key 一起被使用

1.8 rows

該查詢一共掃描了多少行。

這是一個估計值,不準确。

mysql> explain insert into t(c, d) (select c + 1, d from t force index (c) order by c desc limit 1);
+----+-------------+-------+------------+-------+---------------+------+---------+------+------+----------+--------------------------------------+
| id | select_type | table | partitions | type  | possible_keys | key  | key_len | ref  | rows | filtered | Extra                                |
+----+-------------+-------+------------+-------+---------------+------+---------+------+------+----------+--------------------------------------+
|  1 | INSERT      | t     | NULL       | ALL   | NULL          | NULL | NULL    | NULL | NULL |     NULL | NULL                                 |
|  1 | SIMPLE      | t     | NULL       | index | NULL          | c    | 5       | NULL |    1 |   100.00 | Backward index scan; Using temporary |
+----+-------------+-------+------------+-------+---------------+------+---------+------+------+----------+--------------------------------------+
2 rows in set, 1 warning (0.00 sec)      

1.9 filtered

此查詢條件所過濾的資料的百分比

1.10 extra

額外資訊:

using filesort

性能消耗大,需要額外的一次查詢(排序)。

使用EXPLAIN可以檢查MySQL是否可以使用索引來解析ORDER BY子句:

Extra列不包含Using filesort,則使用索引,并且不執行檔案排序

Extra列包含Using filesort,則不使用索引,而是執行全檔案排序

實戰講解MySQL的expain執行計劃,面試官當場要了我(中)

EXPLAIN不能區分優化器是否在記憶體中執行檔案排序。在優化程式trace輸出中可以看到記憶體檔案排序的使用。查找filesort_priority_queue_optimization即可。

對于單索引,若

排序和查找是同一字段,則不會出現該方式

不是,則會出現。

對于聯合索引,不能跨列(最左比對原則)

using temporary

  • 建立臨時表儲存中間結果,查詢完成之後把臨時表删除。

using index(性能提升)

表示目前的查詢是覆寫索引,直接從索引中讀取資料,而無需通路原資料表(回表)。即需要使用到的列,全部都在索引中。

  • 若同時出現using where,則索引被用來執行索引鍵值的查找
  • 若沒有,則索引被用來讀取資料,而不是真的查找

using index condition

MySQL 5.6後加入的新特性(Index Condition Pushdown)。會先條件過濾索引,過濾完索引後找到所有符合索引條件的資料行,随後用 WHERE 子句中的其他條件去過濾這些資料行。

實戰講解MySQL的expain執行計劃,面試官當場要了我(中)

using where(需回表查詢)

使用where進行條件過濾。

假設 age 為索引,如下 SQL

select age,name from ... where age =       

using join buffer

使用連接配接緩存

impossible where

where語句的結果總是false

no matching row in const table

對于具有聯接的查詢,存在一個空表或沒有滿足唯一索引條件的行的表。

實戰講解MySQL的expain執行計劃,面試官當場要了我(中)

其實還有很多,不再過多描述。

explain extended

MySQL 4.1引入explain extended指令,通過explain extended 加上show warnings可以檢視MySQL 真正被執行之前優化器所做的操作

explain select * from users;
show warnings;      

可從warning字段看到,會去除一些恒成立的條件,可以利用explain extended的結果來迅速的擷取一個更清晰易讀的sql語句。