/* 1.在innodb中每一個數據頁的大小默認是16KB 2.對於普通索引來講,在查詢時查到知足條件的第一天記錄的時候須要查找下一個記錄,直到碰到第一個不知足 k=5 條件 的記錄 3.對於惟一索引來講由於定義了惟一性,因此查到第一個知足條件的記錄後就會中止查詢 普通索引和惟一索引的性能差別微乎其微 change buffer 在內存中有緩存這mysql數據頁,若是在更新的時候,把磁盤內容改了,可是內存數據還沒改回出現數據不一致,這時候就須要 change buffer,innodb會將這些更新操做緩存在change buffer,下次若是須要訪問這個數據頁,將這個數據頁讀入內存,而後執行change buffer中有關這個數據頁的操做,最終仍是會將數據寫入磁盤。 change buffer 這個操做應用到原數據頁,獲得新結果的過程叫作merge 那麼什麼狀況下可使用change buffer? 惟一索引;對於惟一索引來講,全部的更新操做多會先判斷這個操做是否違反了惟一約束,好比要插入一條(4,400)須要先判斷一下表中是否存在k=4這條記錄,而且是必需要將數據頁讀入內存才能判斷。若是都已經讀入內存了,,那直接更新內存會更快,就不必使用change buffer, 所以惟一索引的更新就不能使用change buffer了,實際上也只有普通索引可使用 change buffer 用的是 buffer pool 裏的內存,所以不能無限增大。change buffer 的大小,能夠經過參數 innodb_change_buffer_max_size 來動態設置。這個參數設置爲 50 的時候,表示 change buffer 的大小最多隻能佔用 buffer pool 的 50%。 第一種狀況:這個更新的目標記錄在內存中,在innodb中一條更新操做是如何執行的,一條新數據(4,500) 惟一:找到3和5的這個位置判斷有沒有衝突,若是沒有插入數據。 普通:找到3和5的位置,插入數據 他們的區別是多了一個判斷,這對於cpu來講差別很微小 第二種狀況:這個記錄要更新的目標數據頁不在內存中 惟一:先將目標數據頁讀入內存中,判斷目標是否衝突,再來寫入 普通:將更新操做記錄在change buffer中,執行結束 change buffer減小了對磁盤的隨機訪問,因此對更新的性能提高仍是明顯的 change buffer的應用場景 經過上面咱們知道change buffer對更新操做的加速過程,且只限於普通索引,而不適用於惟一索引。 問題:普通索引的全部應用場景都適用於change buffer嗎? change buffer是將咱們對一個數據頁的更新操做記錄下來,因此在一個數據頁作merge前,change buffer記錄的變動越多(也就是更新次數越多),收益越大 所以對於寫多讀少的業務來講,頁面在寫完立刻被訪問的機率小,此時使用change buffer的效果最好 這種常見業務有,帳單,日誌等 反之,若是一個業務寫完立刻就作查詢,那麼即便知足條件,將更新先記錄在change buffer,但立刻進行訪問,會當即觸發merge過程,這樣隨機訪問IO次數並不會減小,還會增長change buffer 的維護代價,因此這種業務使用change buffer反而會起副作用。 因此普通索引和惟一索引到底該如何選擇 咱們知道在查詢方面他們是沒什麼差異,主要是考慮在更新上面的性能。因此儘可能選擇普通索引 若是在更新後立刻會進行查詢操做,應該關閉change buffer ,而在其餘狀況下change buffer都能有明顯的性能提高 如何開啓關閉change buffer呢? 能夠經過參數innodb_change_buffering來控制是否啓用change buffer。 --all: 默認值。開啓buffer inserts、delete-marking operations、purges --none: 不開啓change buffer --inserts: 只是開啓buffer insert操做 --deletes: 只是開delete-marking操做 --changes: 開啓buffer insert操做和delete-marking操做 --purges: 對只是在後臺執行的物理刪除操做開啓buffer功能 爲何change buffer可以支持數據持久化呢? change buffer 會將操做記錄在redo log若是服務器意外關閉,在redo log這個日誌文件中還有記錄 redo log 這個主要是用來節省隨機寫入IO磁盤的消耗(轉爲順序寫) 而change buffer這個是來節省隨機讀IO磁盤的消耗 */