MySQL explain 洞悉SQL執行全過程

2021-10-19 13:15:33 字數 3243 閱讀 2800

系統負載高、響應慢,在db層面,低效的sql很有可能是罪魁禍首!

explain關鍵字是mysql提供用於分析sql執行的具體資訊,比如 掃瞄型別、索引、掃瞄行數、排序、臨時檔案等等

explain可用於select, delete, insert, replace以及 update語句之前;

column

json name

meaning

idselect_id

the select identifier

select_type

none

the select type

table

table_name

the table for the output row

partitions

partitions

the matching partitions

type

access_type

the join type

possible_keys

possible_keys

the possible indexes to choose

keykey

the index actually chosen

key_len

key_length

the length of the chosen key

refref

the columns compared to the index

rows

rows

estimate of rows to be examined

filtered

filtered

percentage of rows filtered by table condition

extra

none

additional information

其中關鍵的幾列:

type: 描述表的join關係,由好到壞:system > const > eq_ref > ref > fulltext > ref_or_null > index_merge > unique_subquery > index_subquery > range > index > all;其中除了all全表掃瞄外,其他型別都會通過索引優化 進而減少掃瞄行數

possible_keys: 當前sql**現的索引, 也就是當前sql可能會引用的索引

key:最終選擇的索引列

key_len: 表示使用的索引長度,是以位元組為單位

ref: 引用字段,如果是使用的常數等值查詢,這裡會顯示const;如果是關聯查詢,這裡是 驅動表的某個字段(關聯查詢時通常驅動表的某個欄位是被驅動表中建立索引乙個字段);如果條件使用了表示式或者函式,或者條件列發生了內部隱式轉換,這裡可能顯示為func

rows: 表示的是預計掃瞄行數

filtered:表示返回結果的行數佔 rows 的百分比(最大值是100);在rows一定的情況下,filtered列的值越小越好,因為對於被驅動表來說,其掃瞄次數由驅動表的rows x filtered決定。例如,如果rows為1000,過濾後(where子句過濾)為50.00(50%),則需要與下表連線的行數為1000 × 50% = 500 檢視

extra: 輸出查詢計畫的一些額外重要資訊,比如檔案排序、索引等等

system: 表裡只有一行資料,根據條件將這行資料查詢出來

const:最多匹配表中的一行資料,通常是primary key or unique index查詢

eq_ref: join操作時,驅動表a與被驅動表b,a表的驅動欄位f通常是b表的主鍵id或者b表的唯一鍵

ref: 一般是通過普通索引匹配少量資料時的型別。例如,join操作時,驅動表a與被驅動表b,a表的驅動欄位f通常是b表的非主鍵id或者b表的非唯一鍵,也就是只是b表的普通索引鍵,這一點正好和eq_ref型別互補

ref_or_null: 與ref型別相似,不同是加了is null條件處理為空的查詢

index_merge:多索引查詢,然後合併各索引搜尋的結果集

range: 通過索引查詢的結果集通常是乙個資料行數不小的範圍

index:這種型別的效率僅優於all,會先掃瞄索引樹,如果要求返回的列可以滿足要求就直接返回不用進行回表操作了,否則會將滿足條件的所有資料都進行回表查詢資料

all: 全表掃瞄

using filesort: 表示需要排序。當需要通過order by子句有序輸出時,如果待排序內容超過了緩衝區大小,則會借助於檔案排序的方式來完成排序操作

using index: 使用覆蓋索引,不需要回表。查詢欄位從索引樹(普通索引)就可以拿到的情況就不會通過回表的方式從聚簇索引(也就是主鍵索引)索取資料,節約的回表操作可以減少i/o操作

using index condition: 聯合索引上使用索引下推盡可能多的過濾掉不滿足where條件的資料,從而減少i/o操作

using join buffer:join連表查詢會使用到join buffer。block nested loop 和 batched key access演算法會使用。

using mrr: multi-range read優化策略,通常情況下我們會通過普通索引快速定位到主鍵id,然後回表從聚簇索引上獲取資料;雖然在普通索引上是順序訪問,但在聚簇索引樹上很有可能是通過隨機訪問的方式,因此,該優化策略通過將從普通索引獲取的主鍵id排序後,然後順序訪問的方式訪問聚簇索引樹

using temporary:表示使用了臨時表。分為記憶體臨時表和磁碟臨時表,記憶體臨時表有一定的限制,達到限制之後需要使用磁碟臨時表儲存中間資料。通常可能在group by, order by 以及union操作(會去重) 可能會使用內部臨時表

using where:使用where條件過濾

index nested-loop join(nlj):驅動錶走全表掃瞄,被驅動表通過索引掃瞄

block nested-loop join(bnl):被驅動欄位不存在索引,因此被驅動表也只能走全表掃瞄,此時通過join buffer,將驅動表的資料一塊塊讀到join buffer, 然後從被驅動表一條條讀取資料做join操作(與join buffer中的資料對比),重複這兩步操作,直到join操作完成;由此可見合理設定join buffer大小至關重要,join buffer越大分塊放入次數越少, i/o次數也就越少

batched key access(bka):是nlj演算法的優化版本。借助於mrr優化操作,將多條主鍵id暫存join buffer,排序後從聚簇索引讀取資料,因為磁碟順序讀取的效率也很高

參考文件

mysql5.7

mysql explain欄位說明

explain列的解釋 id 查詢的序列號 select type select查詢的型別,主要是區別普通查詢和聯合查詢 子查詢之類的複雜查詢。table 所訪問的資料庫中表的名稱。type 這是重要的列,顯示連線使用了何種型別。從最好到最差的連線型別為const eq reg ref range ...

Mysql explain 執行計畫

使用方法,在select語句前加上explain就可以了 如 explain select from test1 explain列的解釋 table 顯示這一行的資料是關於哪張表的 type 這是重要的列,顯示連線使用了何種型別。從最好到最差的連線型別為const eq reg ref range ...

MySql Explain解釋說明

explain解釋說明 explain顯示了mysql如何使用索引來處理select語句以及連線表。可以幫助選擇更好的索引和寫出更優化的查詢語句。使用方法,在select語句前加上explain就可以了 如 explain select surname,first name form a,b whe...