MySQL索引和執行計劃

索引

索引(Index)是幫助MySQL高效獲取數據的數據結構。可以得到索引的本質:索引是數據結構

在這裏插入圖片描述
右側是數據表,一共有兩列七條記錄,最左邊的是數據記錄的物理地址

索引分類

  • 普通索引:即一個索引只包含單個列,一個表可以有多個單列索引
  • 唯一索引:索引列的值必須唯一,但允許有空值
  • 複合索引:即一個索引包含多個列
  • 聚簇索引(聚集索引):並不是一種單獨的索引類型,而是一種數據存儲方式。具體細節取決於不同的實現,InnoDB的聚簇索引其實就是在同一個結構中保存了B-Tree索引(技術上來說是B+Tree)和數據行。
  • 非聚簇索引:不是聚簇索引,就是非聚簇索 show global variables like “%datadir%”;

語法

  • 查看索引
SHOW INDEX FROM table_name
  • 創建索引
CREATE  [UNIQUE ] INDEX indexName ON mytable(columnname(length));
ALTER TABLE 表名 ADD  [UNIQUE ]  INDEX [indexName] ON (columnname(length)) 
  • 刪除索引
 DROP INDEX [indexName] ON mytable;

執行計劃

使用EXPLAIN關鍵字可以模擬優化器執行SQL查詢語句,從而知道MySQL是如何處理你的SQL語句的。分析你的查詢語句或是表結構的性能瓶頸

執行計劃的作用

  • 表的讀取順序
  • 數據讀取操作的操作類型
  • 哪些索引可以使用
  • 哪些索引被實際使用
  • 表之間的引用
  • 每張表有多少行被優化器查詢

執行計劃包含的信息

在這裏插入圖片描述

執行計劃-ID

select查詢的序列號,包含一組數字,表示查詢中執行select子句或操作表的順序,id值越大優先級越高,越先被執行

執行計劃-select_type

在這裏插入圖片描述
查詢的類型,主要是用於區別普通查詢、聯合查詢、子查詢等的複雜查詢
在這裏插入圖片描述

執行計劃-table

顯示這一行的數據是關於哪張表的

執行計劃-type

type顯示的是訪問類型,是較爲重要的一個指標,結果值從最好到最壞依次是:system>const>eq_ref>ref>range>index>ALL

  • system
    表只有一行記錄(等於系統表),這是const類型的特列,平時不會出現,這個也可以忽略不計
  • const
    表示通過索引一次就找到了
    const用於比較primary key或者unique索引。因爲只匹配一行數據,所以很快,如將主鍵置於where列表中,MySQL就能將該查詢轉換爲一個常量
  • eq_ref
    唯一性索引掃描,對於每個索引鍵,表中只有一條記錄與之匹配。常見於主鍵或唯一索引掃
  • ref
    非唯一性索引掃描,返回匹配某個單獨值的所有行
  • range
    只檢索給定範圍的行,使用一個索引來選擇行。key 列顯示使用了哪個索引
    一般就是在你的where語句中出現了between<>in等的查詢
  • index
    全表掃描的一種,但只掃描索引文件
  • all
    Full Table Scan,將遍歷全表以找到匹配的行
執行計劃-possible_keys

可能會使用到的索引

執行計劃-key

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

查詢中若使用了覆蓋索引,則該索引和查詢的select字段重疊

執行計劃-key_len

表示索引中使用的字節數,可通過該列計算查詢中使用的索引的長度。在不損失精確性的情況下,長度越短越好

key_len顯示的值爲索引字段的最大可能長度,並非實際使用長度,即key_len是根據表定義計算而得,不是通過表內檢索出的。根據這個值,就可以判斷索引使用情況,特別是在組合索引的時候,判斷所有的索引字段是否都被查詢用到。
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述

datetime類型在5.6中字段長度是5個字節

變長字段需要額外的2個字節(VARCHAR值保存時只保存需要的字符數,另加一個字節來記錄長度(如果列聲明的長度超過255,則使用兩個字節),所以VARCAHR索引長度計算時候要加2),固定長度字段不需要額外的字節。

而NULL都需要1個字節的額外空間,所以索引字段最好不要爲NULL,因爲NULL讓統計更加複雜並且需要額外的存儲空間。

複合索引有最左前綴的特性,如果複合索引能全部使用上,則是複合索引字段的索引長度之和,這也可以用來判定複合索引是否部分使用,還是全部使用

執行計劃-ref

顯示索引的哪一列被使用了,如果可能的話,是一個常數。哪些列或常量被用於查找索引列上的值

執行計劃-rows

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

執行計劃-Extra

在這裏插入圖片描述
覆蓋索引(Covering Index),一說爲索引覆蓋。

  • 理解方式一:就是select的數據列只用從索引中就能夠取得,不必讀取數據行,MySQL可以利用索引返回select列表中的字段,而不必根據索引再次讀取數據文件,換句話說查詢列要被所建的索引覆蓋。
  • 理解方式二:索引是高效找到行的一個方法,但是一般數據庫也能使用索引找到一個列的數據,因此它不必讀取整個行。畢竟索引葉子節點存儲了它們索引的數據;當能通過讀取索引就可以得到想要的數據,那就不需要讀取行了。一個索引包含了(或覆蓋了)滿足查詢結果的數據就叫做覆蓋索引

如果要使用覆蓋索引,一定要注意select列表中只取出需要的列,不可select *

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章