![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiI0gTMx81dsQWZ4lmZf1GLlpXazVmcvwFciV2dsQXYtJ3bm9CX9s2RkBnVHFmb1clWvB3MaVnRtp1XlBXe0xCMy81dvRWYoNHLwEzX5xCMx8FesU2cfdGLwMzX0xiRGZkRGZ0Xy9GbvNGLpZTY1EmMZVDUSFTU4VFRR9Fd4VGdsYTMfVmepNHLrJXYtJXZ0F2dvwVZnFWbp1zczV2YvJHctM3cv1Ce-cmbw5SO0gjM5EGZ5gjM0cjNiJGZyYzXwATM1YTMzIzLcdDMyIDMy8CXn9Gbi9CXzV2Zh1WavwVbvNmLvR3YxUjLyM3Lc9CX6MHc0RHaiojIsJye.png)
作者: 西魏陶淵明
西魏陶淵明
莫笑少年江湖夢,誰不少年夢江湖
這篇文章主要講 explain 如何使用,還有 explain 各種參數概念,之後會講優化
# 一、Explain 用法
explain模拟Mysql優化器是如何執行SQL查詢語句的,進而知道Mysql是如何處理你的SQL語句的。分析你的查詢語句或是表結構的性能瓶頸。
文法:
Explain + SQL 語句;
如:
Explain select * from user;
會生成如下 SQL 分析結果,下面詳細對每個字段進行詳解
# 1. id
是一組數字,代表多個表之間的查詢順序,或者包含子句查詢語句中的順序,id 總共分為三種情況,依次詳解
# id相同
id相同,執行順序由上至下
# id不同
id 不同,如果是子查詢,id 号會遞增,id 值越大優先級越高,越先被執行
# id相同和不同
id 相同和不同的情況同時存在
# 2. select_type
select_type 包含以下幾種值
simple
、
primary
、
subquery
、
derived
、
union
、
union result
# simple
簡單的
select
查詢,查詢中不包含子查詢或者
union
查詢
# primary
如果 SQL 語句中包含任何子查詢,那麼子查詢的最外層會被标記為
primary
# subquery
在
select
或者
where
裡包含了子查詢,那麼子查詢就會被标記為
subQquery
,同三.二同時出現
# derived
在
from
中包含的一個子查詢,會被标記為衍生查詢,會把查詢結果放到一個臨時表中
# union / union result
如果有兩個
select
查詢語句,他們之間用
union
連起來查詢,那麼第二個
select
會被标記為
union
,
union
的結果被标記為
union result
。它的 id 是為 null 的
# 3. table
表示這一行的資料是哪張表的資料
# 4. type
type 是代表 MySQL 使用了哪種索引類型,不同的索引類型的查詢效率也是不一樣的,type 大緻有以下種類。 越往上性能越高。
Type類型 | 說明 |
system | 表中隻有一行記錄,system 是 const 的特例,幾乎不會出現這種情況,可以忽略不計 |
const | 必須是用主鍵索引或者唯一索引放到 where 條件中查詢 |
eq_ref | 多表查詢中,索引查出來的資料都是唯一的(不能是多個,也不能是0個),常見于唯一索引和主鍵索引 |
ref | 不是主鍵索引,也不是唯一索引,就是普通的索引,可能會傳回多個符合條件的行。 |
range | 展現在對某個索引進行區間範圍檢索,一般出現在 where 條件中的 between、and、<、>、in 等範圍查找中。 |
index | 将所有的索引樹都周遊一遍,查找到符合條件的行。索引檔案比資料檔案還是要小很多,是以比不用索引全表掃描還是要快很多。 |
all | 沒用到索引,單純的将表資料全部都周遊一遍,查找到符合條件的資料 |
# 5. possible_keys
此次查詢中涉及字段上若存在索引,則會被列出來,表示可能會用到的索引,但并不是實際上一定會用到的索引
# 6. key
此次查詢中實際上用到的索引
# 7. key_len
表示索引中使用的位元組數,通過該屬性可以知道在查詢中使用的索引長度,注意:這個長度是最大可能長度,并非實際使用長度,在不損失精确性的情況下,長度越短查詢效率越高
# 8. ref
顯示關聯的字段。如果使用常數等值查詢,則顯示 const,如果是連接配接查詢,則會顯示關聯的字段。
- tb_emp 表為非唯一性索引掃描,實際使用的索引列為 idx_name,由于 tb_emp.name='rose'為一個常量,是以 ref=const。
- tb_dept 為唯一索引掃描,從 sql 語句可以看出,實際使用了 PRIMARY 主鍵索引,ref=db01.tb_emp.deptid 表示關聯了 db01 資料庫中 tb_emp 表的 deptid 字段。
# 9. rows
根據表資訊統計以及索引的使用情況,大緻估算說要找到所需記錄需要讀取的行數,rows 越小越好
# 10. extra
不适合在其他列顯示出來,但在優化時十分重要的資訊
# using fileSort(重點優化)
俗稱 " 檔案排序 " ,在資料量大的時候幾乎是“九死一生”,在 order by 或者在 group by 排序的過程中,order by 的字段不是索引字段,或者 select 查詢字段存在不是索引字段,或者 select 查詢字段都是索引字段,但是 order by 字段和 select 索引字段的順序不一緻,都會導緻 fileSort
如果where後面的查詢和order by的索引,不是一個值。就會出現fileSort。
複合索引,誇界,也會出現fileSort。
優化建議: where 什麼就order by 什麼。 或者 where和order by 按照複合索引順序,不要跨列或者無序使用
# using temporary(重點優化)
使用了臨時表儲存中間結果,常見于 order by 和 group by 中。
優化建議: 查詢哪些列就用哪些列來order by。 能不用建立臨時表就不要建立。
# USING index(重點)
索引覆寫,就是目前sql查詢不用讀取原檔案,隻用讀取索引。因為查詢的列就是索引列
表示相應的 select 操作中使用了覆寫索引(Coveing Index),避免通路了表的資料行,效率不錯!如果同時出現 using where,表明索引被用來執行索引鍵值的查找;如果沒有同時出現 using where,表面索引用來讀取資料而非執行查找動作。
# Using where
跟using index相反,要回表去查詢。
表明使用了 where 過濾
# Using join buffer
使用了連接配接緩存
# impossible where
where 子語句的值總是 false,不能用來擷取任何資料。出現這個就要檢查sql。