【mysql】InnoDB關鍵特性---插入緩衝

要想深刻的理解InnoDB插入緩衝特性,我們需要對mysql的索引有比較深刻的理解。

聚集索引和非聚集索引

聚集索引聚集索引是指數據庫錶行中數據的物理順序與鍵值的邏輯(索引)順序相同。

在InnoDB中,表中的數據都是按照主鍵順序存放。而聚集索引就是按照每張表的主鍵構造一棵B+樹,同時葉子節點中存放的就是整張表的行記錄數據,也將聚集索引的葉子節點稱爲數據頁。同B+樹結構一樣,每隔數據頁都通過一個雙向鏈表進行鏈接。

由於實際的數據結構只能按照一棵B+樹進行排序,因此每張表只能擁有一個聚集索引。

我覺得下面這張圖還是很形象的表達出了B+樹的結構以及聚集索引。。。。
在這裏插入圖片描述

又找了一組圖:聚集索引,葉子節點上索引和數據是在一起的,找到索引也就找到了數據。
在這裏插入圖片描述
非聚集索引該索引中索引的邏輯順序與磁盤上行的物理存儲順序不同,也稱爲輔助索引。

對於輔助索引,葉子節點並不包含行記錄的全部數據,葉子節點除了包含鍵值(輔助索引的鍵值)以外,每個葉子節點中的索引行中還包含了一個書籤,該書籤用來高速InnoDB存儲引擎哪裏可以找到與索引相對應的行數據(其實就是主鍵索引),通過主鍵索引再去找到具體的行數據。

在這裏插入圖片描述

插入性能

在InnoDB存儲引擎中,主鍵是行唯一的標識符。通常應用程序中行記錄的插入順序是按照主鍵遞增的順序進行插入的。因此,插入聚集索引一般是順序的,不需要磁盤的隨機讀取,因此速度是非常快的

當然主鍵僅限於自增型,如果是UUID這種本身沒有順序性,插入時跟輔助索引一樣,效率也會很低。

爲什麼輔助索引插入效率低呢?

CREATE TABLE t(
	a INT AUTO_INCREMENT,
	b VARCHAR(30),
	PRIMARY KEY(a),
	key(b)
);

如表 t 中對 b 建立一個輔助索引。當我們向表中插入一條數據時,因爲表中的數據是按照主鍵a的順序排序的,但是對於非聚集索引b的葉子節點的插入不再是順序的了,這時就需要離散的訪問非聚集索引頁,離散的訪問非聚集索引頁導致性能下降。

爲什麼需要訪問非聚集索引頁呢?

因爲非聚集索引也是需要排序的,每次插入新的數據,不僅要按照主鍵進行排序,同時也需要將數據按照非聚集索引在非聚集索引頁中進行索引排序。在非聚集索引頁中找到輔助索引所在的位置進行插入,這樣由於隨機讀取的存在會導致插入操作性能下降。

插入緩衝技術(Insert Buffer)

Insert Buffer需要滿足兩個條件:

  • 索引是輔助索引
  • 索引不是唯一的。
    如果索引是唯一索引的話,在插入時,還需要去查找索引頁中來判斷記錄的唯一性,這樣又會有離散讀取索引頁的情況發生,從而導致了Insert Buffer失去了意義。

當同時滿足以上兩個條件時,InnoDB存儲引擎纔會使用Insert Buffer。

Insert Buffer 實現:

Insert Buffer是一棵B+樹,因此他也分爲非葉子節點和葉子節點兩部分。
非葉子節點存放的是查詢的search key值,結構如圖:

|space| marker | offset |

search key一共佔用9個字節,space表示待插入記錄所在表的表空間id,在InnoDB存儲引擎中,每個表有一個唯一的space id,可以通過space id查詢得知是哪張表,space佔用4字節,marker是用來兼容老版本的Insert Buffer,佔用1字節,offset則表示頁所在的偏移量,佔用4字節。

而對於葉子節點的結構如下圖:

| space | marker | offset | metadata | …| … | …| …|

前面字段含義和空間和非葉子節點相同,metadata字段用來記錄一些額外信息,例如插入記錄的順序等,從第5列開始,就是實際插入記錄的各個字段了。

當一個輔助索引要插入到頁(space,offset)時,如果這個也不在緩衝池中,那麼InnoDB存儲引擎首先根據上述規則構造一個search key,接下來查詢Insert Buffer這棵B+樹,然後將這條記錄插入到Insert Buffer B+樹的葉子節點中。

當記錄插入到Insert Buffer B+樹中後,真正將記錄合併到數據庫表記錄是通過merge Insert Buffer進行的(j將多個插入操作合併成一個執行)。爲了保證每次Merge Insert Buffer成功執行,還需要有一個特殊的頁用來標記每個輔助索引頁(space,page_no)的可用空間。這個頁的類型爲Insert Buffer Bitmap.

發生MergeBuffer的幾種情況:

  • 輔助索引頁被讀取到緩衝池時
  • Insert Buffer Bitmap頁追蹤到該輔助索引頁已無可用空間時;
  • Master Thread

查看Merge Insert Buffer

用戶可用通過SHOW ENGINE INNODB STATUS來查看插入緩衝的信息:
seg size代表 Insert Buffer大小,size代表已經合併記錄頁的數量,inserts代表了插入記錄數,merged recs代表了合併的插入記錄數量,merges代表合併的次數,也就是實現讀取頁的次數。

以上是關於InnoDB Insert Buffer相關的內容。

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