添加小編微信帶您進入Java交流社區
小編微信:372787553 備註進羣
前言
在較早的MySQL版本中,分區和擴展信息是使用 EXPLAIN PARTITIONS
和生成的 EXPLAIN EXTENDED
。仍然可以識別這些語法的向後兼容性,但是默認情況下現在啓用了分區和擴展輸出,因此PARTITIONS
和EXTENDED
關鍵字已不再使用。使用它們會導致警告,並且EXPLAIN
在將來的MySQL版本中會將其從語法中刪除。
你不能使用已棄用PARTITIONS
,並EXTENDED
在相同的關鍵字共同 EXPLAIN
聲明。此外,這些關鍵字都不能與該FORMAT
選項一起使用 。
如果您不知道您所使用的Mysql的版本號,請輸入如下命令進行查看:
SELECT version();
注
本文以Mysql 5.7.28
進行講解
解釋輸出列
每個輸出行EXPLAIN
提供有關一個表的信息。
EXPLAIN 內容解釋
列 | JSON名稱 | 含義 |
---|---|---|
id |
select_id |
該SELECT 標識符 |
select_type |
沒有 | 該SELECT 類型 |
table |
table_name |
輸出行表 |
partitions |
partitions |
匹配的分區 |
type |
access_type |
連接類型 |
possible_keys |
possible_keys |
可能的索引選擇 |
key |
key |
實際選擇的索引 |
key_len |
key_length |
所選鍵的長度 |
ref |
ref |
與索引比較的列 |
rows |
rows |
估計要檢查的行 |
filtered |
filtered |
按表條件過濾的行百分比 |
Extra |
沒有 | 附加信息 |
注:JSON屬性
NULL
不會顯示在JSON格式的EXPLAIN
輸出中。
-
id
(JSON名:select_id
)SELECT
標識符。這是SELECT
查詢中的序號 。NULL
如果該行引用其他行的並集結果,則該值爲。在這種情況下,該table
列顯示的值類似於 表明該行引用的行的並 集是和的值 。 -
select_type
(JSON名稱:無)類型
SELECT
,可以是下表中顯示的任何類型。JSON格式EXPLAIN
將SELECT
類型公開 爲a的屬性query_block
,除非它爲SIMPLE
或PRIMARY
。表格中還會顯示JSON名稱(如果適用)。select_type
值JSON名稱 含義 SIMPLE
沒有 簡單 SELECT
(不使用UNION
或子查詢)PRIMARY
沒有 最外層 SELECT
UNION
沒有 第二個或之後的 SELECT
陳述UNION
DEPENDENT UNION
dependent
(true
)中的第二個或更高版本的 SELECT
語句UNION
,取決於外部查詢UNION RESULT
union_result
的結果 UNION
。SUBQUERY
沒有 首先 SELECT
在子查詢DEPENDENT SUBQUERY
dependent
(true
)首先 SELECT
在子查詢中,取決於外部查詢DERIVED
沒有 派生表 MATERIALIZED
materialized_from_subquery
物化子查詢 UNCACHEABLE SUBQUERY
cacheable
(false
)子查詢,其結果無法緩存,必須針對外部查詢的每一行重新進行評估 UNCACHEABLE UNION
cacheable
(false
)UNION
屬於不可緩存子查詢的中的第二個或更高版本的選擇(請參閱參考資料UNCACHEABLE SUBQUERY
)DEPENDENT
通常表示使用相關子查詢。 -
table
(JSON名:table_name
)輸出行所引用的表的名稱。這也可以是以下值之一:
- <unionM,N>:該行指的是具有和
id
值的行 的 *M
*並集N
。 - <derived*
N
*>:該行是指用於與該行的派生表結果id
的值N
。派生表可能來自(例如)FROM
子句中的子查詢 。 - <subquery*
N
>:該行是指該行的物化子查詢的結果,其id
值爲N
*。
- <unionM,N>:該行指的是具有和
-
partitions
(JSON名:partitions
)查詢將從中匹配記錄的分區。該值適用
NULL
於未分區的表。 -
type
(JSON名:access_type
)連接類型。有關不同類型的描述,請參見
EXPLAIN
連接類型 -
possible_keys
(JSON名:possible_keys
)該
possible_keys
列指示MySQL可以選擇從中查找表中各行的索引。請注意,此列完全獨立於表的順序,如的輸出所示EXPLAIN
。這意味着possible_keys
在實踐中,某些鍵可能無法與生成的表順序一起使用。如果此列是
NULL
(或在JSON格式的輸出中未定義),則沒有相關的索引。在這種情況下,您可以通過檢查該WHERE
子句以檢查它是否引用了一些適合索引的列,從而提高查詢性能。如果是這樣,請創建一個適當的索引並EXPLAIN
再次檢查查詢 。要查看錶具有哪些索引,請使用。
SHOW INDEX FROM
tbl_name
-
key
(JSON名:key
)該
key
列指示MySQL實際決定使用的密鑰(索引)。如果MySQL決定使用possible_keys
索引之一來查找行,則將該索引列爲鍵值。可能
key
會命名該值中不存在的索引possible_keys
。如果所有possible_keys
索引都不適合查找行,但是查詢選擇的所有列都是其他索引的列,則可能發生這種情況。也就是說,命名索引覆蓋了選定的列,因此儘管不使用索引來確定要檢索的行,但索引掃描比數據行掃描更有效。對於
InnoDB
,即使查詢也選擇了主鍵,輔助索引也可能覆蓋選定的列,因爲InnoDB
主鍵值與每個輔助索引一起存儲。如果key
爲NULL
,則MySQL沒有找到可用於更有效地執行查詢的索引。要強制MySQL使用或忽略列出的索引
possible_keys
列,使用FORCE INDEX
,USE INDEX
或IGNORE INDEX
在您的查詢。對於
MyISAM
表,運行ANALYZE TABLE
有助於優化器選擇更好的索引。 -
key_len
(JSON名:key_length
)該
key_len
列指示MySQL決定使用的密鑰的長度。的值key_len
使您能夠確定MySQL實際使用的多部分鍵的多少部分。如果該key
列顯示NULL
,則該key_len
列也顯示NULL
。由於密鑰存儲格式的原因,一列可以使用的密鑰長度
NULL
比一NOT NULL
列大。 -
ref
(JSON名:ref
)該
ref
列顯示將哪些列或常量與該key
列中命名的索引進行比較,以 從表中選擇行。如果值爲
func
,則使用的值是某些函數的結果。要查看哪個功能,請使用SHOW WARNINGS
以下EXPLAIN
命令查看擴展EXPLAIN
輸出。該函數實際上可能是算術運算符之類的運算符。 -
rows
(JSON名:rows
)該
rows
列指示MySQL認爲執行查詢必須檢查的行數。對於
InnoDB
表,此數字是估計值,可能並不總是準確的。 -
filtered
(JSON名:filtered
)該
filtered
列指示將被表條件過濾的錶行的估計百分比。最大值爲100,這表示未過濾行。值從100減小表示過濾量增加。rows
顯示了檢查的估計行數,rows
×filtered
顯示了將與下表連接的行數。例如,如果rows
爲1000且filtered
爲50.00(50%),則與下表連接的行數爲1000×50%= 500。 -
Extra
(JSON名稱:無)此列包含有關MySQL如何解析查詢的其他信息。
該
Extra
列沒有對應的JSON屬性 ;但是,此列中可能出現的值顯示爲JSON屬性或該message
屬性的文本。
連接類型說明
該type
列 EXPLAIN
輸出介紹如何連接表。在JSON格式的輸出中,這些作爲access_type
屬性的值找到。以下列表描述了連接類型,從最佳類型到最差類型:
-
system
該表只有一行(=系統表)。這是
const
連接類型的特例 。 -
const
該表最多具有一個匹配行,該行在查詢開始時讀取。因爲只有一行,所以優化器的其餘部分可以將這一行中列的值視爲常量。
const
表非常快,因爲它們只能讀取一次。const
在將aPRIMARY KEY
或UNIQUE
index的所有部分與常數值進行比較時使用。在以下查詢中,*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;
-
eq_ref
對於先前表中的每行組合,從此表中讀取一行。除了
system
和const
類型,這是最好的連接類型。當連接使用索引的所有部分並且索引爲aPRIMARY KEY
或UNIQUE NOT NULL
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;
-
ref
對於先前表中的每個行組合,將從該表中讀取具有匹配索引值的所有行。
ref
如果連接僅使用鍵的最左前綴,或者如果鍵不是aPRIMARY KEY
或UNIQUE
索引(換句話說,如果連接無法根據鍵值選擇單個行),則使用。如果使用的鍵僅匹配幾行,則這是一種很好的連接類型。ref
可以用於使用=
或<=>
運算符進行比較的索引列 。在以下示例中,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;
-
fulltext
使用
FULLTEXT
索引執行連接。 -
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;
-
index_merge
此連接類型指示使用索引合併優化。在這種情況下,
key
輸出行中的列包含使用的索引列表,並key_len
包含使用的索引 的最長鍵部分的列表。 -
unique_subquery
此類型替換 以下形式的
eq_ref
]某些IN
子查詢:value IN (SELECT primary_key FROM single_table WHERE some_expr)
unique_subquery
只是一個索引查找函數,它完全替代了子查詢以提高效率。 -
index_subquery
此連接類型類似於
unique_subquery
。它代替IN
子查詢,但適用於以下形式的子查詢中的非唯一索引:value IN (SELECT key_column FROM single_table WHERE some_expr)
-
range
使用索引選擇行,僅檢索給定範圍內的行。的
key
輸出行中的列指示使用哪個索引。將key_len
包含已使用的時間最長的關鍵部分。該ref
列NULL
適用於此類型。range
當一個鍵列使用任何的相比於恆定可使用=
,<>
,>
,>=
,<
,<=
,IS NULL
,<=>
,BETWEEN
,LIKE
,或IN()
運營商:SELECT * FROM tbl_name WHERE key_column = 10; SELECT * FROM tbl_name WHERE key_column BETWEEN 10 and 20; SELECT * FROM tbl_name WHERE key_column IN (10,20,30); SELECT * FROM tbl_name WHERE key_part1 = 10 AND key_part2 IN (10,20,30);
-
index
該
index
連接類型是一樣的ALL
,只是索引樹被掃描。這發生兩種方式:- 如果索引是查詢的覆蓋索引,並且可用於滿足表中所需的所有數據,則僅掃描索引樹。在這種情況下,
Extra
列爲Using index
。僅索引掃描通常比索引掃描更快,ALL
因爲索引的大小通常小於表數據。 - 使用對索引的讀取執行全表掃描,以按索引順序查找數據行。
Uses index
沒有出現在Extra
列中。
當查詢僅使用屬於單個索引一部分的列時,MySQL可以使用此連接類型。
- 如果索引是查詢的覆蓋索引,並且可用於滿足表中所需的所有數據,則僅掃描索引樹。在這種情況下,
-
ALL
對來自先前表的行的每個組合進行全表掃描。如果該表是未標記的第一個表
const
,則通常不好,在其他所有情況下通常 非常糟糕。通常,可以ALL
通過添加索引來避免這種情況,這些 索引允許基於早期表中的常量值或列值從表中檢索行。
本文的分享暫時就到這裏,希望對您有所幫助
關注 Java有貨領取更多資料
聯繫小編。微信:372787553,帶您進羣互相學習
左側小編微信,右側獲取免費資料
- SpringCloud 自定義封裝架構https://github.com/yanghaiji/javayh-platform
- Java 設計模式學習代碼 https://github.com/yanghaiji/design-pattern
- SpringCloud學習代碼: https://github.com/yanghaiji/javayh-cloud
- AlibabaCloud學習代碼:https://github.com/yanghaiji/javayh-cloud-nacos
- SpringBoot+Mybatis 多數據源切換:https://github.com/yanghaiji/javayh-boot-data-soure
- Redis、Mongo、Rabbitmq、Kafka學習代碼: https://github.com/yanghaiji/javayh-middleware
- SpringBoot+SpringSecurity實現自定義登錄學習代碼:https://github.com/yanghaiji/javayh-distribution