為啥不推薦使用uuid作為Mysql資料庫的主鍵呢
? 在mysql中設計表的時候,mysql官方并不推薦使用uuid或者不連續不重復的雪花id,而是推薦使用連續自增的主鍵id,
? 官方推薦的是auto_increment,主要原因是uuid在資料量較大的情況下,效率直線下滑,
使用uuid和自增id的索引結構對比
使用自增id的內部結構
? 自增的主鍵的值是順序的,所以Innodb把每一條記錄都存盤在一條記錄的后面,當達到頁面的最大填充因子的時候(innodb是15/16)
? 下一條記錄會寫入新的頁中,一旦資料按照這種順序的方式加載,主鍵頁就會近乎于順序的記錄填滿,提升了頁面的最大填充率,不會有頁的浪費
? 新插入的行一定會在原有的最大資料行的下一行,mysql定位和尋址很快,不會為計算新行的位置而做出額外的消耗
? 減少了頁分裂和碎片的產生
缺點
- 別人容易根據自增的id爬取資料庫,從而分析資料
- 對于高并發的負載,innodb在按主鍵進行插入的時候會造成明顯的鎖爭用,主鍵的上界會成為爭搶的熱點,因為所有的插入都發生在這里,并發插入會導致間隙鎖競爭
- @Auto_Increment鎖機制會造成自增鎖的搶奪,有一定的性能損失
使用uuid的索引內部結構
? 因為uuid毫無規律可言,新值和舊值大小無法確定,所以需要innodb要為新行尋找新的合適的位置從而來分配新的空間,會導致以下幾個問題:
- 寫入的目標頁很可能已經重繪到磁盤上并且從快取上移除,或者還沒有被加載到快取中,innodb在插入之前不得不先找到并從磁盤讀取目標頁到記憶體中,這就導致了大量的隨機IO
- 因為寫入是亂序的,所以innodb不得不頻繁的做頁分裂操作,以便為新的行分配空間,頁分裂導致移動大量的資料,一次插入最少修改三個頁以上
- 由于頻繁的頁分裂,頁會變得稀疏并被不規則的填充,最侄訓倒是資料有碎片
把隨機值(uuid和雪花id)載入到聚簇索引(innodb默認的索引型別)以后,有時候會需要做一次OPTIMEIZE TABLE來重建表并優化頁的填充,這將又需要一定的時間消耗,
總結:
? 使用innodb應該盡可能的按主鍵的自增順序插入,并且盡可能使用單調的增加的聚簇鍵的值來插入新行
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/62964.html
標籤:其他
