唯?索引普通索引選擇難題
面試經(jīng)常被問,核?是需要回答到change buffer,那change buffer?是個什么東?呢?
當(dāng)需要更新?個數(shù)據(jù)?時,如果數(shù)據(jù)?在內(nèi)存中就直接更新,?如果這個數(shù)據(jù)?還沒有在內(nèi)存中的話,
在不影響數(shù)據(jù)?致性的前提下,InooDB會將這些更新操作緩存在change buffer中,這樣就不需要從磁
盤中讀?這個數(shù)據(jù)?了
在下次查詢需要訪問這個數(shù)據(jù)?的時候,將數(shù)據(jù)?讀?內(nèi)存,然后執(zhí)?change buffer中與這個?有關(guān)的
操作,通過這種?式就能保證這個數(shù)據(jù)邏輯的正確性。
需要說明的是,雖然名字叫作change buffer,實際上它是可以持久化的數(shù)據(jù)。也就是說,change buffer
在內(nèi)存中有拷?,也會被寫?到磁盤上。
將change buffer中的操作應(yīng)?到原數(shù)據(jù)?,得到最新結(jié)果的過程稱為merge。
除了訪問這個數(shù)據(jù)?會觸發(fā)merge外,系統(tǒng)有后臺線程會定期merge。在數(shù)據(jù)庫正常關(guān)閉(shutdown)
的過程中,也會執(zhí)?merge操作。

顯然,如果能夠?qū)⒏虏僮飨扔涗浽赾hange buffer,減少讀磁盤,語句的執(zhí)?速度會得到明顯的提升。
?且,數(shù)據(jù)讀?內(nèi)存是需要占?buffer pool的,所以這種?式還能夠避免占?內(nèi)存,提?內(nèi)存利?率
那么,什么條件下可以使?change buffer呢?
對于唯?索引來說,所有的更新操作都要先判斷這個操作是否違反唯?性約束。
要判斷表中是否存在這個數(shù)據(jù),?這必須要將數(shù)據(jù)?讀?內(nèi)存才能判斷,如果都已經(jīng)讀?到內(nèi)存了,那
直接更新內(nèi)存會更快,就沒必要使?change buffer了。
因此,唯?索引的更新就不能使?change buffer,實際上也只有普通索引可以使?。
change buffer?的是buffer pool?的內(nèi)存,因此不能?限增?,change buffer的??,可以通過參數(shù)
innodb_change_buffer_max_size來動態(tài)設(shè)置,這個參數(shù)設(shè)置為50的時候,表示change buffer的??最
多只能占?buffer pool的50%。
將數(shù)據(jù)從磁盤讀?內(nèi)存涉及隨機IO的訪問,是數(shù)據(jù)庫??成本最?的操作之?,change buffer因為減少
了隨機磁盤訪問,所以對更新性能的提升是會很明顯的
change buffer的使?場景
因為merge的時候是真正進?數(shù)據(jù)更新的時刻,?change buffer的主要?的就是將記錄的變更動作緩存
下來,所以在?個數(shù)據(jù)?做merge之前,change buffer記錄的變更越多(也就是這個??上要更新的次
數(shù)越多),收益就越?。
因此,對于寫多讀少的業(yè)務(wù)來說,??在寫完以后?上被訪問到的概率?較?,此時change buffer的使
?效果最好,這種業(yè)務(wù)模型常?的就是賬單類、?志類的系統(tǒng)。
反過來,假設(shè)?個業(yè)務(wù)的更新模式是寫?之后?上會做查詢,那么即使?jié)M?了條件,將更新先記錄在
change buffer,但之后由于?上要訪問這個數(shù)據(jù)?,會?即觸發(fā)merge過程。這樣隨機訪問IO的次數(shù)不
會減少,反?增加了change buffer的維護代價,所以,對于這種業(yè)務(wù)模式來說,change buffer反?起到
了副作?