問題:當乙個字段同時滿足唯一索引和普通索引的情況下,我們要如何抉擇呢?
要弄清楚這個問題,我們首先要了解唯一索引和普通索引的實現原理,我們通過查詢操作和更新操作分別來對比他們之間的區別
附帶一提,普通索引和唯一索引的區別:首先,他們都是索引,然後從字面上來看,普通,就是可重複的索引,唯一索引,就是不可重複的索引。因此他們倆的區別就是乙個key可以重複,乙個不可重複。
普通索引:查詢到滿足條件的第乙個記錄後,需要查詢下乙個記錄,直到碰到第乙個不滿足條件的記錄。
唯一索引:由於索引定義了唯一性,查詢到第乙個滿足條件的記錄後,就會停止繼續檢索。
因此,普通索引相對於唯一索引要多一些操作。但是,他們之間對於效能的差距卻是微乎其微,想知道為什麼的朋友可以自己去查詢一下相關資料。
為了說明普通索引和唯一索引對更新語句效能的影響這個問題,我需要先跟你介紹一下change buffer,
當需要更新乙個資料頁時,如果資料頁在記憶體中就直接更新,而如果這個資料頁還沒有在記憶體中的話,在不影響資料一致性的前提下,
inoodb 會將這些更新操作快取在 change buffer 中,這樣就不需要從磁碟中讀入這個資料頁了。
在下次查詢需要訪問這個資料頁的時候,將資料頁讀入記憶體,然後執行 change buffer 中與這個頁有關的操作。
通過這種方式就能保證這個資料邏輯的正確性。需要說明的是,雖然名字叫作 change buffer,實際上它是可以持久化的資料。也就是說,
change buffer 在記憶體中有拷貝,也會被寫入到磁碟上。
將 change buffer 中的操作應用到原資料頁,得到最新結果的過程稱為 merge。除了訪問這個資料頁會觸發 merge 外,系統有後台執行緒會定期 merge。
在資料庫正常關閉(shutdown)的過程中,也會執行 merge 操作。
顯然,如果能夠將更新操作先記錄在 change buffer,減少讀磁碟,語句的執行速度會得到明顯的提公升。
而且,資料讀入記憶體是需要占用 buffer pool 的,所以這種方式還能夠避免占用記憶體,提高記憶體利用率。
了解了change buffer之後,我要跟大家說的是,只有普通索引才能使用change buffer,唯一索引的更新不能使用change buffer。
但是並不是說,有change buffer就會更好,我們根據上面的原理可以了解到,change buffer是在業務下一次做查詢的時候,就會觸發merge的過程,
這樣隨機訪問 io 的次數不會減少,反而增加了 change buffer 的維護代價。
因此在更新操作後馬上就要查詢的業務情景下,你應該關閉 change buffer, 而在其他情況下,change buffer 都能提公升更新效能。
回到我們文章開頭的問題,普通索引和唯一索引應該怎麼選擇。
其實,這兩類索引在查詢能力上是沒差別的,主要考慮的是對更新效能的影響。
所以,我建議你盡量選擇普通索引。
MySQL實戰45講之6 唯一索引和普通索引
change buffer和redo log的區別 很容易被混淆的兩個概念,都是為了減少磁碟的io操作,但是在更新一條語句的時候,其實是有先後順序的,也就是看此資料葉在不在記憶體中,如果資料葉在記憶體中,那麼更新操作會先在redo log中更改資料,然後等空閒再寫磁碟,這樣減少寫磁碟。但是如果資料葉...
mysql普通索引和唯一索引選擇
mysql普通索引和唯一索引的區別 所以,普通索引和唯一索引的主要區別在於插入和修改,換個說法就是能否使用change buffer,那麼change buffer就是是什麼,有什麼用就是我們接下來要討論的話題。change buffer中儲存的是mysql的更新操作 從名字上就能看出來 當我們在更...
MySQL 普通索引 唯一索引和主索引
1 普通索引 普通索引 由關鍵字key或index定義的索引 的唯一任務是加快對資料的訪問速度。因此,應該只為那些最經常出現在查詢條件 wherecolumn 或排序條件 orderbycolumn 中的資料列建立索引。只要有可能,就應該選擇乙個資料最整齊 最緊湊的資料列 如乙個整數型別的資料列 來...