普通索引與惟一索引的選擇問題

說到這個問題以前,首先咱們須要先了解一下change buffer數據庫

當須要更新一個數據頁時,若是數據頁在內存中就直接更新,而若是這個數據頁尚未在內存中的話,在不影響數據一致性的前提下,InooDB 會將這些更新操做緩存在 change buffer 中,這樣就不須要從磁盤中讀入這個數據頁了。在下次查詢須要訪問這個數據頁的時候,將數據頁讀入內存,而後執行 change buffer 中與這個頁有關的操做。經過這種方式就能保證這個數據邏輯的正確性。緩存

須要說明的是,雖然名字叫做 change buffer,實際上它是能夠持久化的數據。也就是說,change buffer 在內存中有拷貝,也會被寫入到磁盤上。性能

將 change buffer 中的操做應用到原數據頁,獲得最新結果的過程稱爲 merge。除了訪問這個數據頁會觸發 merge 外,系統有後臺線程會按期 merge。在數據庫正常關閉(shutdown)的過程當中,也會執行 merge 操做。spa

顯然,若是可以將更新操做先記錄在 change buffer,減小讀磁盤,語句的執行速度會獲得明顯的提高。並且,數據讀入內存是須要佔用 buffer pool 的,因此這種方式還可以避免佔用內存,提升內存利用率。線程

那麼,什麼條件下可使用 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

由於 merge 的時候是真正進行數據更新的時刻,而 change buffer 的主要目的就是將記錄的變動動做緩存下來,因此在一個數據頁作 merge 以前,change buffer 記錄的變動越多(也就是這個頁面上要更新的次數越多),收益就越大。後臺

所以,對於寫多讀少的業務來講,頁面在寫完之後立刻被訪問到的機率比較小,此時 change buffer 的使用效果最好。這種業務模型常見的就是帳單類、日誌類的系統。

回到咱們開頭的問題,普通索引和惟一索引應該怎麼選擇。其實,這兩類索引在查詢能力上是沒差異的,主要考慮的是對更新性能的影響。因此,我建議你儘可能選擇普通索引。

相關文章
相關標籤/搜索