本文學習了開發者應如何選擇索引
這裡先有乙個前提 , 那就是系統中的業務**保證不會向目標字段寫入兩個相同的值, 這個前提是非常理想化的了
那麼此時對於目標表中新增乙個普通索引 還是 對目標字段設定唯一索引選擇的問題而言 , 如何做出選擇使效能最大化呢?
效能我們可以從查詢和更新這兩種操作來分析
我們假設新增的普通索引欄位為k
由於普通索引並未做唯一性約束, 因此
對於普通索引, 當查詢到第乙個k==5
的字段時,會繼續向下搜尋,直到找到第乙個不滿足where條件的記錄
對於唯一索引, 當查詢到第乙個滿足條件的記錄時 , 查詢過程終止
但是 , 上述兩種操作的效能差距很小.
原因在於innodb的資料讀寫機制
由於讀寫磁碟i/o操作的成本很大 ,因此在讀取資料的時候,是先將資料從磁碟讀入記憶體中,並以頁為單位組織.
既然資料已經存入記憶體了 , 那普通索引的查詢方式就只是多移動幾次指標的問題了, 速度與唯一索引相差不大
同樣地 , 受innodb讀寫機制的影響 , 當需要更新一行資料時 , 如果資料已經存到記憶體中了, 就對其直接更新
但是如果資料未讀入記憶體呢? 這時就需要引入另乙個技術點change buffer了
前文說過 , 對於磁碟的讀寫成本是很大的. 因此 , innodb會將更新操作快取到change buffer中. 當下一次訪問這個資料頁時 , 從磁碟中讀入該資料頁 (這個讀入的資料頁是未做更新操作的 , 即,儲存著更新以前的資料). 然後innodb會對其做一次change buffer中快取下來的操作(這個過程稱為merge) ,以此保證資料的一致性
· 效能分析 :
需要更新的目標頁在記憶體中(假設要插入的索引值為3):
顯然 , 這種情況下效能差異幾乎沒有
需要更新的目標頁不在記憶體中
此時普通索引的效能更高 , 而唯一索引則會導致一系列問題如: 系統阻塞 , 記憶體利用率不高
change buffer在記憶體中又拷貝 , 同時也需要存入磁碟做持久化, 實質上是持久化了的資料
使用場景 :change buffer 僅限於普通索引, 尤其是對於讀多寫少的業務而言 , 對效能提公升較大
然而 , change buffer 也有其受限的情況: 當做完更新操作後 , 立馬要讀取資料的業務而言 ,merge操作會頻繁觸發, 適得其反
change buffer 和 redo log :二者都是用於記錄資料庫操作的 但是, redo log主要用於節省隨機寫磁碟的io消耗, 而change buffer 則是用於節省隨機讀磁碟的io消耗
具體問題具體分析 , 對於開頭設定的這種理想情況而言 , 索引確保唯一,我們可以選擇使用普通索引
然而如果業務**無法保證唯一性 , 那還是老實用唯一索引吧!
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 中的資料列建立索引。只要有可能,就應該選擇乙個資料最整齊 最緊湊的資料列 如乙個整數型別的資料列 來...