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