mysql筆記系列(七)唯一索引和普通索引的性能區別


 

普通索引和唯一索引,應該怎么選擇?
在innodb中每個頁的大小為16kb,讀一條記錄時以頁為單位讀入內存。

普通索引查找數據的時候,會將符合條件的都找出來
唯一索引,只要找到第一條符合條件的,就會立刻返回,不再繼續找了,因為唯一的約束已經事先確保了只有一條符合條件。
但是對查詢來說,以上兩種 如果數據都只有1條,時間是相似的,微乎其微。

change buffer
當更新一個數據頁的時候,如果數據頁在內存中就直接更新,如果這個數據頁還沒有在內存中的話,在不影響數據一致性的前提下,innoDB會將這些更新操作緩存到change buffer中,這樣就不需要從磁盤中讀入這個數據頁了,下次遇到這個數據頁讀到內存的時候,就把changebuffer中的更新merege到 這個數據頁上面。

注意:雖然是叫changeBuffer 但是這個也是會持久化到硬盤中的。 merege操作除了在訪問數據頁的時候會觸發,在系統后台也會定期merege ,在數據庫正常關閉(shutdown)的過程中,也會執行merge操作。

這個優化 把更新操作在內存中進行,減少磁盤的讀寫,可以極大提高性能。

changerbuffer不能被唯一索引用到,因為唯一索引每次更新都要判斷這個操作是否違反唯一性約束,比如說要插入某個數據,要先判斷其是否已經存在,那就必須要將這個數據頁讀入內存中才知道,既然都讀入到內存中,那么直接更新就好了,不需要changebuffer。 因此這個只能被普通索引用到。

那么對於插入來說,
1.如果目標數據頁在內存中
普通索引
先找到數據位置,然后插入
唯一索引
先找到數據位置,然后判斷是否違反唯一鍵約束,然后插入

2.如果目標數據頁不在內存中
普通索引
將數據更新到changebuffer ,執行結束
普通索引
將數據頁加載到內存中,先找到數據位置,然后判斷是否違反唯一鍵約束,然后插入

因此 唯一索引和普通索引在查詢的時候 區別不大,但是在插入操作的時候,區別很大。
因為是否讀磁盤 對性能影響很大。

因此 如果業務可以保證唯一性的情況下,普通索引優先於唯一索引。

changebuffer的適用場景:
如果數據是寫多讀少,那么效果將非常明顯,因為寫入的數據被立刻訪問的概率小。

如果數據是讀多寫少,因為讀的時候會將數據頁加到內存,會觸發merege , 如果每次寫入到changebuffer中就立刻觸發merge ,那還不如直接加載到內存中寫入,因為這樣並沒有減少隨機IO,反而增加了changebuffer的維護負擔。

如果碰上了大量插入數據慢、內存命中率低的時候,可以考慮排查下是不是唯一索引的影響,因為有唯一索引的數據插入,每次都要加載數據頁到內存,然后判斷是否存在.

注意下:隨機IO和順序IO的區別,隨機是在任意位置,順序則是從頭到尾或者從尾到頭, 效率上來說,隨機IO要比順序IO低的多,因為磁盤讀寫, 隨機讀寫需要不斷的移動磁頭或者切換磁道。

changebuffer和redolog 的區別:
changebuffer是寫在內存中,將原本要寫到磁盤中的數據緩存到了內存中,減少了磁盤IO。
redolog則是寫在磁盤中,是將原本寫到文件中的隨機IO, 變成了順序IO,提高了效率。

注意!change buffer 一開始是寫內存的,那么如果這個時候機器掉電重啟,會不會導致 change buffer 丟失呢?change buffer 丟失可不是小事兒,再從磁盤讀 入數據可就沒有了 merge 過程,就等於是數據丟失了。會不會出現這種情況?

答案是不會,因為這個操作記錄,在事務提交的時候,也被寫入到了redolog里面,崩潰恢復的時候,changeBuffer也會從redolog里面恢復回來。

merge的過程:
1.從磁盤讀入老數據到內存
2.從changebuffer找到這個數據頁的記錄,更新上去
3.寫redolog, redolog里面包含了數據的變更和changebuffer的變更。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM