天天看點

MySQL執行計劃

一、MySQL執行計劃

在MySQL中可以通過explain關鍵字模拟優化器執行SQL語句,進而知道MySQL是

如何處理SQL語句的。

二、MySQL整個查詢執行過程

用戶端向MySQL伺服器發送一條查詢請求

伺服器首先檢查查詢緩存(看下緩存中是否有該查詢語句的執行計劃),如果命中緩存,則立刻傳回存儲在緩存中的結果(這個過程叫軟解析,當表執行更新或者表結構發生改變會删除緩存)。否則進入下一階段

伺服器進行SQL解析(先執行文法檢查,然後再執行語意檢查檢視對象是否存在)、預處理(優化處理)、再由優化器生成對應的執行計劃

MySQL根據執行計劃,調用存儲引擎的API來執行查詢

将結果傳回給用戶端,同時緩存查詢結果

三、啟動執行計劃

explain select 投影列 from 表名 where 條件

四、explain 列的解析

ID:

查詢執行順序:

id值相同時表示從上向下執行

id值相同被視為一組

如果是子查詢,id 值會遞增,id 值越高,優先級越高

select_tepy:

simple:表示查詢中不包含子查詢或者union

primary:當查詢中包含任何複雜的子部分,最外層的查詢被标記成primary

derived:在from的清單中包含的子查詢被标記成derived

subquery:在select或where清單中包含了子查詢,則子查詢被标記成subquery

union:兩個select查詢時前一個标記為PRIMARY,後一個标記為UNION。union 出現

在from從句子查詢中,外層select标記為PIRMARY, union中第一個查 詢為DERIVED,

第二個子查詢标記為UNION

unionresult:從union表擷取結果的select 被标記成union result

table:

顯示這一行的資料是關于哪張表的。

type:

這是重要的列,顯示連接配接使用了何種類型。從最好到最差的連接配接類型為system、const、eq_reg、 ref、 range、 index和ALL.

1、system:表中隻有一-行資料。屬于const的特例。如果實體表中就一行資料為ALL。

2、const: 查詢結果最多有一個比對行。因為隻有一行,是以可以被視為常量。const查詢速度非常快,因為隻讀一次。一般情況下把主鍵或唯一索引作為唯一條件的查詢都是const

3、eq_ ref:查詢時查詢外鍵表全部資料。且隻能查詢主鍵列或關聯列。且外鍵表中外鍵列中資料不能有重複資料,且這些資料都必須在主鍵表中有對應資料(主鍵表中資料可以有沒有用到的) .

4、ref:相比eq_ref, 不對外鍵列有強制要求,裡面的資料可以重複,隻要出現重複的資料取值就是ref。也可能是索引查詢。

5、range:把這個列當作條件隻檢索其中一個範圍。常見where從句中出現between、<、in等。主要應用在具有索引的列中

6、index:這個連接配接類型對前面的表中的每一個記錄聯合進行完全掃描 (比ALL更好,因為索引一般小于表資料)。

7、ALL:全盤掃描,這個連接配接類型對于前面的每-一個記錄聯合進行完全掃描,這一般比較糟糕, 應該盡量避免。

possible_ keys:

查詢條件字段涉及到的索引,可能沒有使用。

Key:

實際使用的索引。如果為NULL,則沒有使用索引。

Key_len:

表示索引中使用的位元組數,查詢中使用的索引的長度(最大可能長度),并非實際使用

長度,理論上長度越短越好。key _len是根據表定義計算而得的,不是通過表内檢索出的。

ref:

顯示索引的哪一列被使用了, 如果可能的話,是一個常量const。

rows:

根據表統計資訊及索引選用情況,大緻估算出找到所需的記錄所需要讀取的行數。

Fitered:

顯示了通過條件過濾出的行數的百分比估計值。

extra:

查詢的額外資訊:

1、Distinct:MySQL發現第1個比對行後,停止為目前的行組合搜尋更多的行。

2、Not exists:MySQL能夠對查詢進行LEFT JOIN優化,發現1個比對LEFT JOIN标準的行後,不再為前面的的行組合在該表内檢查更多的行。

3、range checked for each record (index map: #):MySQL沒有發現好的可以使用的索引,但發現如果來自前面的表的列值已知,可能部分索引可以使用。

4、Using filesort:MySQL需要額外的一次傳遞,以找出如何按排序順序檢索行。

5、Usingindex:從隻使用索引樹中的資訊而不需要進一步搜尋讀取實際的行來檢索表中的列資訊。

6、Using temporary:為了解決查詢,MySQL需要建立一個臨時表來容納結果。

7、Using where:WHERE子句用于限制哪個一行比對下一個表或發送到客戶。

8、Using sort_ union(...)、 Using union(...)、Using intersec(...):這些函數說明如何為index_ merge聯接類型合并索引掃描。

9、Using index for group-by:類似于通路表的Using index方式,Using index for group-by表示MySQL發現了一個索引,可以用來查詢GROUP BY或DISTINCT查詢的所有列,而不要額外搜尋硬碟通路實際的表。