Mysql技術內幕InnoDB儲存引擎讀書筆記--《五》索引與演算法

FreeeLinux發表於2017-07-01

B +樹索引的管理

目前Mysql資料庫存在的一個普遍問題是,所有對於索引的新增或者刪除操作,Mysql資料庫是先建立一張臨時表,然後把資料匯入臨時表,刪除原表,再把臨時表重名為原來的表名。因此對於一張大表,新增和刪除索引需要很長的時間。
InnoDB儲存引擎從版本InnoDB Plugin開始,支援一種稱為快速索引建立方法。當然這種方法只限定於輔助索引,對於主鍵的建立和刪除還是需要重建一張表。對於輔助索引的建立,InnoDB儲存引擎會對錶加上一個S鎖。在建立的過程中,不需要重建表,因此速度極快。但是在建立的過程中,由於上了S鎖,因此建立的過程中該表只能進行讀操作。刪除輔助索引的操作就更簡單了,只需要在InnoDB儲存引擎的內部檢視更新下,將輔助索引的空間標記為可用,並刪除Mysql內部檢視上對該表的索引定義即可。

show index 每個列的含義:

  • Table:索引所在的表名
  • Non_unique:非唯一的索引,可以看到primary key是0, 因此必須是唯一的。
  • Key_name:索引的名稱,我們可以通過這個名稱來DROP INDEX。
  • Seq_in_index:索引中該列的位置,如果看聯合索引idx_a_b就比較直觀了。
  • Column_name:索引的列。
  • Collation:列以什麼方式儲存在索引中。可以是A或者NULL。B+樹總是A,即排序的。如果使用了Heap儲存引擎,並且建立了Hash索引,這裡就會顯示出NULL了。因為Hash根據Hash桶來存放索引資料,而不是對資料進行排序。
  • Cardinality:非常關鍵的值,表示索引中唯一值的數目的估計值。Cardinality表的行數應儘可能接近1,如果非常小,那麼需要考慮是否還需要建立這個索引。
  • Sub_part:是否是列的部分被索引。如果看idx_b這個索引,這裡顯示100,表示我們只索引b列的前100個字元。如果索引整個列,則該欄位為NULL。
  • Packed:關鍵字如何被壓縮。如果沒有被壓縮,則為NULL。
  • NULL:是否索引的列含有NULL值。如果有為YES。
  • Index_type:索引的型別
  • Comment:註釋

索引時機

Mysql資料庫的優化器會通過EXPLAIN的rows欄位預估查詢可能得到的行,如果大於某一個值,則B+樹會選擇全表掃描。一般取出的資料量超過表中資料的20%,優化器就不會使用索引,而是進行全表的掃描。

預讀取

InnoDB有兩個預讀方法,稱為隨機預讀取(random read ahead)和線性預讀取(linear read ahead)預讀取。隨機預讀是指當一個區(64個連續頁)中的13個頁也在緩衝區中,並在LRU列表的前端(即頁是頻繁的被訪問),則InnoDB儲存引擎會將這個區中所有頁預讀到緩衝區。線性預讀基於緩衝池中頁的訪問模式,而不是數量。如果一個區中的24個頁都被順序的訪問了,則InnoDB儲存引擎會預讀取下一個區的所有頁。

InnoDB儲存疫情的雜湊演算法

InnoDB儲存引擎使用雜湊演算法對字典進行查詢,其衝突機制採用連結串列方式,雜湊函式採用除法雜湊方式。對於緩衝池頁的雜湊表來說,在緩衝池中的Page頁都有一個chain指標,它指向相同雜湊函式值的頁。而對於除法雜湊,m的取值為略大於2倍緩衝池頁數量的質數。

InnoDB儲存引擎的表空間都有一個space號,我們要查詢的應該是某個表空間的某個連續16KB的頁,即偏移量offset。InnoDB儲存引擎將space左移20位,然後加上這個space和offset,即關鍵字K=space<<20+offset,然後通過除法雜湊到各個槽中。

相關文章