MySQL的explain工具介绍
文章目錄
- 介紹
- explain extended
- show warings
- explain partitions
- id 字段
- select_type
- type
- key
- possible_keys
- key_len
- key_len 計算規(guī)則
- ref
- rows
- extra
介紹
使用 explain 可以模擬優(yōu)化器執(zhí)行 SQL 語句,會返回 SQL 語句的執(zhí)行計劃信息,但是不會真正去執(zhí)行這條 SQL 語句。
注:如果 from 中包含子查詢,則會真正執(zhí)行子查詢,將結(jié)果放入臨時表中(衍生表)。
explain extended
會在 explain 的基礎(chǔ)上額外返回 filtered,根據(jù) rows*(filtered/100) 可以估算出將要和前一個表進行連接的行數(shù)。前一個表是指相對于當(dāng)前表靠后執(zhí)行的表,即 id 值更小的表
5.7 版本后不需要加 extended。
show warings
在 explain 語句后面緊跟著 show warings 語句,可以得到優(yōu)化后的查詢語句,從而看出優(yōu)化器優(yōu)化了什么。
mysql> EXPLAIN EXTENDED SELECT * from `user` where `NAME` LIKE 'zhangsan' \G *************************** 1. row ***************************id: 1select_type: SIMPLEtable: userpartitions: NULLtype: ALL possible_keys: NULLkey: NULLkey_len: NULLref: NULLrows: 3filtered: 33.33Extra: Using where 1 row in set, 2 warnings (0.00 sec)mysql> SHOW WARNINGS \G *************************** 1. row ***************************Level: WarningCode: 1681 Message: 'EXTENDED' is deprecated and will be removed in a future release. *************************** 2. row ***************************Level: NoteCode: 1003 Message: /* select#1 */ select `test`.`user`.`id` AS `id`,`test`.`user`.`NAME` AS `NAME` from `test`.`user` where (`test`.`user`.`NAME` like 'zhangsan') 2 rows in set (0.00 sec)explain partitions
相比 explain 多了個 partitions 字段,如果查詢是基于分區(qū)表的話,會顯示查詢將訪問的分區(qū)。
5.7 版本后不需要加 partitions。
id 字段
mysql> explain select (select 1 from actor where id = 1) from (select * from film where id = 1) der;執(zhí)行計劃信息如下:
id 值越大,表示越優(yōu)先執(zhí)行。上圖中可以看到 from 子句中的衍生表查詢的優(yōu)先級最高,所以最先執(zhí)行;接著執(zhí)行 select 子句中的子查詢;最后執(zhí)行最外面的主查詢。
select_type
simple:簡單查詢
primary:復(fù)雜查詢中的最外層的查詢
subquery:包含在 select 子句中的子查詢
derived:包含在 from 子句中的子查詢,derived 表示衍生的,因為 from 子句中的子查詢結(jié)果會放入臨時表中,其實就是一個衍生表
type
system:表示查詢的表只有一條記錄,所以查詢效率很高。這種類型不需要優(yōu)化
const:表示查詢條件是某個具體的索引值,例如主鍵索引或者唯一索引,所以表最多有一條匹配的數(shù)據(jù)記錄,只要讀取1次,效率很高。這種類型不需要優(yōu)化。
range:表示查詢條件是某個區(qū)間,最好要優(yōu)化到這個類型
eq_ref:在多表關(guān)聯(lián)查詢時,主鍵所在表的查詢類型就是 eq_ref,因為主鍵是唯一的;當(dāng)然如果使用唯一鍵關(guān)聯(lián)查詢也屬于這種類型。這種類型的查詢基本不要優(yōu)化了
ref:表示查詢條件使用普通索引,而不是唯一索引,結(jié)果可能是多條記錄
index:掃描全索引就能拿到結(jié)果,一般是掃描某個二級索引,這種掃描不會從索引樹根節(jié)點開始快速査找,而是直接對二級索引的葉子節(jié)點遍歷和掃描,速度還是比較慢的,這種査詢一般為使用覆蓋索引,二級索引一般比較小,所以這種通常比 all 快一些。但是也要優(yōu)化
all:表示全表掃描,效率很低,需要優(yōu)化
key
查詢語句用到的索引名稱
possible_keys
執(zhí)行 SQL 語句可能會用到的索引,但是最后執(zhí)行時不一定用到
key_len
這一列顯示了mysq 在索引里使用的字節(jié)數(shù),通過這個值可以算出具體使用了復(fù)合索引中的哪些列。舉例來說,film_actor 表的聯(lián)合索引 idx_film_actor_id 由 film_id 和 actor_id 兩個 int 列組成,并且每個 int 是 4 字節(jié)。通過結(jié)果中的 key_len=4 可推斷出查詢使用了第一個列:film_id 列來執(zhí)行索引查找。
key_len 計算規(guī)則
1.字符串
char(n):n字節(jié)長度
varchar((n):如果是u-8,則長度 3n+2 字節(jié),加的2字節(jié)用來存儲字符串長度數(shù)值
2.數(shù)值類型
tinyint:1字節(jié)
smallint:2字節(jié)
int:4字節(jié)
bigint:8字節(jié)
3.時間類型
date:3字節(jié)
timestamp:4字節(jié)
datetime:8字節(jié)
注意:
1.如果字段允許為 NULL,需要 1 字節(jié)記錄是否為 NULL
2.索引最大長度是 768 字節(jié),當(dāng)字符串過長時,MySQL 會做一個類似左前綴索引的處理,將前半部分的字符提取出來做索引
ref
查詢語句中,如果查詢條件使用了常量,則會顯示 const,如下:
mysql> select * from film_actor where film_id = 2 and actor_id = 5;執(zhí)行計劃信息:
注:如果多表關(guān)聯(lián)查詢,這個 ref 會顯示關(guān)聯(lián)中的唯一索引字段。
rows
查詢語句可能掃描的行數(shù)
extra
using index:表示使用覆蓋索引
using where:表示使用了 where 子句,且查詢的字段沒有被二級索引全覆蓋,通常查詢語句沒有用到任何索引
using index condition:通常查詢條件使用到了聯(lián)合索引的前面幾個字段,而且查詢的字段沒有完全被二級索引覆蓋
using temporary:表示使用了臨時表處理查詢
using filesort:表示使用索引字段以外的方式進行排序,效率較低
select tables optimized away:使用聚合函數(shù)訪問索引字段
總結(jié)
以上是生活随笔為你收集整理的MySQL的explain工具介绍的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: MySQL联合索引原理_复合索引_组合索
- 下一篇: MySQL的索引优化