用了Change Buffer性能還沒有提升?
Change Buffer是對更新過程有顯著的性能提升。在更新數據的時候,如果數據頁在內存中就直接更新,如果要更新數據的內存頁不在內存中,就會在不影響數據一致性的前提下,數據庫引擎會把更新操作緩存在Change Buffer中,這樣就不需要從磁盤中讀取數據頁,在下一次查詢這個數據頁的時候從磁盤中讀取這個數據頁,然后將Change Buffer中記錄的與這個數據頁有關的操作執行,通過這樣保證數據的準確,這個過程也叫做merge。
我們把更新操作先寫入Change Buffer,減少讀磁盤,更新語句的執行速度就會顯著提升。將更新操作記錄在Change Buffer然后一起merge,減少了數據讀入內存,還可以提高內存利用率。
Change Buffer的merge在查詢相關數據頁的時候會被觸發,系統后臺線程也會定期merge,數據庫正常關閉的時候也會先merge再關閉數據庫。
為什么唯一索引不能使用Change Buffer?
唯一索引在每一次更新的時候都會先查詢要插入的數據是否已經存在,這就必須把數據頁讀入內存中校驗是否違反唯一性約束,如果已經將數據頁讀入內存了,直接更新內存就可以了。
假設我們要往一張表里插入一條數據,我們來看一下唯一索引和普通索引的處理流程有什么不一樣的,我們分兩種情況來看:要更新的數據頁在內存中和要更新的數據頁不在內存中。
一、要更新的數據頁在內存中。
- 唯一索引:先找到要插入的位置,判斷是否存在沖突,然后插入數據,執行結束
- 普通索引:先找到要插入的位置,插入數據,執行結束。
這種情況,唯一索引和普通索引對語句執行速度影響相差不大,也可以忽略不計。
二、要更新的數據頁不在內存中。
- 唯一索引:先將數據頁讀入內存中,然后判斷要插入的位置是否存在沖突,然后插入數據,執行結束。
- 普通索引:將更新記錄寫在Change Buffer中,執行結束。
唯一索引在這個時候就涉及到隨機磁盤訪問,這也是成本最高的操作之一。相應的,普通索引寫Change Buffer就減少了隨機磁盤訪問,就可以顯著提升性能。
所有的普通索引都可以使用Change Buffer?
到這里我們已經知道了Change Buffer對于普通索引的更新操作有加速作用,那么是所有的普通索引都可以使用Change Buffer進行加速嗎?
這個時候我們就要具體業務具體分析,不同的場景使用不同的策略,Change Buffer我們可以看作是把變更記錄緩存下來,所以在merge之前Change Buffer記錄的變更記錄越多,對性能的提升就越大。因此對于寫多讀少的業務場景使用效果就非常好,如歸檔系統、日志系統等。
對于寫入之后很快就做查詢的業務場景,使用Change Buffer,記錄 了更新記錄之后,很快查詢就出發了merge,這樣也不能降低隨機磁盤訪問,還增加了寫Change Buffer,這個地方Change Buffer就反向操作了。如我們OMS系統的訂單表,寫入之后立馬就會做一些了操作都需要查詢。
總結
Change BUffer主要是改善更新操作的性能,建議盡量選擇普通索引,如果寫入之后就查詢的業務場景,就要關閉Change Buffer,除了這種業務場景,Change Buffer都可以提升性能。