InnoDB原理篇:Change Buffer是如何提升索引性能的?
前言
相信很多小伙伴設計索引時,考慮更多的是索引是否能覆蓋大部分的業務場景,卻忽略了索引的性能。
什么?不同的索引,性能還不一樣?
是的,這要從change buffer說起。
?
Change Buffer是什么
MySQL在啟動成功后,會向內存申請一塊內存空間,這塊內存空間稱為Buffer Pool。
Buffer Pool內維護了很多內容,比如緩存頁、各種鏈表、redo log buff、change buffer等等。
回到正題,change buffer是用來干嘛的?
當索引字段內容發生更新時(update、insert、delete),要更新對應的索引頁,如果索引頁在Buffer Pool里命中的話,就直接更新緩存頁。
否則,InnoDB會將這些更新操作緩存在change buffer中,這樣就無需從硬盤讀入索引頁。
下次查詢索引頁時,會將索引頁讀入Buffer Pool,然后將change buffer中的操作應用到對應的緩存頁,得到最新結果,這個過程稱為merge,通過這種方式就能保證數據邏輯的正確性。
不難看出,change buffer通過減少硬盤隨機IO讀與提高內存利用率,讓數據庫的并發能力更強。
如果不了解Buffer Pool、redo log、索引頁是什么,可以看看阿星之前寫的幾篇文章
聊聊redo log是什么?
不會吧,不會吧,還有人不知道 binlog ?
redo log與binlog間的破事
InnoDB原理篇:Buffer Pool為了讓MySQL變快都做了什么
InnoDB原理篇:聊聊數據頁變成索引這件事
持久化
看到這里小伙伴有疑問了,change buffer在內存中,如果萬一MySql實例掛了或宕機了,這次的更新操作不全丟了嗎?
其實不用擔心,InnoDB對這塊有相應的持久化方案,會有后臺線程定期把change buffer持久化到硬盤的系統表空間(ibdata1)。
并且每次change buffer記錄的內容,會寫入到redo log buff中,由后臺線程定期將redo log buff持久化到硬盤的redolog日志。
最后MySql重啟,可以通過ibdata1或redolog恢復change buffer,恢復的過程,分為下面幾種情況
change buffer的數據刷盤到ibdata,直接根據ibdata恢復
change buffer的數據未刷盤,redolog里記錄了change buffer的內容
change buffer寫入redo log,redo log雖做了刷盤但未commit,binlog未刷盤,這部分數據丟失
change buffer寫入redolog,redolog雖做了刷盤但未commit,binlog已刷盤,先從binlog恢復redolog,再從redolog恢復change buffe
change buffer寫入redolog,redolog和binlog都已刷盤,直接從redolog里恢復。
如果不清楚redolog與binlog的可以看看下面這幾篇文章
3-聊聊redo log是什么?
4-不會吧,不會吧,還有人不知道 binlog ?
5-redo log與binlog間的破事
?
如何使用Change Buffer
看到這里,相信大家對change buffer有了基本的認識。
現在可以展開講講change buffer的使用限制。
是的,你沒聽錯,change buffer不能隨隨便便用。
一般我們可以把常用索引分類為下面幾種
其中聚簇索引和唯一索引是無法使用change buffer,因為它們具備唯一性。
當更新唯一索引字段的內容時,需要把相應的索引頁加載進Buffer Pool,驗證唯一性約束,此時都已經讀入到Buffer Pool了,那直接更新會更快,沒必要使用change buffer。
也就是說,只有非唯一索引才能使用change buffer
業務場景
那現在有一個問題,使用change buffer一定可以起到加速作用嗎?
相信大家都清楚merge的時候是將change buffer記錄的操作應用到索引頁。
所以索引頁merge之前,change buffer記錄的越多收益就越大。
因此對于寫多讀少的業務場景,索引頁在寫完以后馬上被訪問到的概率很小,此時change buffer的收益最高。
相反,讀多寫少的業務場景,更新完馬上做查詢,則會觸發change buff立即merge, 不但硬盤隨機IO次沒有減少,還增加change buffer的維護成本。
因此change buff適合寫多讀少的業務場景
選擇索引
由于唯一索引用不上change buffer的優化機制,在業務可以接受的情況下,從性能角度出發建議考慮非唯一索引
如果所有的更新后面,都馬上伴隨著對這個記錄的查詢,應該關閉change buffer,innodb_change_buffering設置為none表示關閉change buffer。
而在其他情況下change buffer都能提升更新性能。
我們可以通過innodb_change_buffer_max_size來動態設置change buffer占用的內存大小,假設參數設置為50的時候,表示change buffer的大小最多只能占用buffer pool的 50%。
最后留個思考題,如果知道redo log一定清楚WAL機制,change buffer與WAL分別提升性能的側重點是什么?
有道無術,術可成;有術無道,止于術
歡迎大家關注Java之道公眾號
好文章,我在看??
總結
以上是生活随笔為你收集整理的InnoDB原理篇:Change Buffer是如何提升索引性能的?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python好学么数学_Python难学
- 下一篇: 让Netty“榨干”你的CPU