聚集(聚簇)索引、非聚集(非聚簇)索引、主鍵自增對聚簇索引的影響

目錄

聚簇索引

非聚簇索引

二級索引

以Mysql的InnoDB爲例

主鍵自增對聚簇索引的好處

主鍵隨機對聚簇索引的壞處


 

首先,聚集和聚簇只是翻譯不同而已,是一個東西,其實挺蠢的

聚簇索引

索引和數據存儲在一塊( 都存儲在同一個B*tree 中)。 一般主鍵索引都是聚餐索引。

Mysql中InnoDB引擎的主鍵索引爲聚簇索引,MyISAM存儲引擎採用非聚集索引。

因爲無法同時把數據行存放在兩個不同的地方,所以一個表只能有一個聚簇索引(不過,覆蓋索引可以模擬多個聚簇索引的情況)。

非聚簇索引

索引數據和存儲數據是分離的,索引和數據指針地址存儲在一塊。

二級索引

也叫輔助索引,也挺蠢的

二級索引存儲的是記錄的主鍵,而不是數據存儲的地址,所以也稱之爲聚簇索引的二級索引。

以Mysql的InnoDB爲例

主鍵索引是聚簇索引。

唯一索引、普通索引、前綴索引等都是二級索引。

主鍵自增對聚簇索引的好處

(摘自:https://www.jianshu.com/p/54c6d5db4fe6,僅作個人備份,瀏覽請看原文)

對於聚簇索引的存儲引擎,數據的物理存放順序與索引順序是一致的,即:只要索引是相鄰的,那麼對應的數據一定也是相鄰地存放在磁盤上的。它只需要一頁一頁地寫,索引結構相對緊湊,磁盤碎片少,效率也高。

由於主鍵的值是順序的,InnoDB把每一條記錄都存儲在上一條記錄的後面。當達到頁的最大填充因子時(InnoDB默認的最大填充因子是頁大小的15/16,留出的部分空間用於以後修改),下一條記錄就會寫入新的頁中。一旦數據按照這樣順序的方式加載,主鍵頁就會近似於被順序的記錄填滿,這也是所期望的結果。

人無完人,總結順序主鍵缺點:

對於高併發工作負載,在InnoDB中按主鍵順序插入可能會造成明顯的爭用。主鍵的上界會成爲“熱點”。因爲所有的插入都發生在這裏,所以併發插入可能導致間隙鎖競爭。另一個熱點可能是auto_increment鎖機制;如果遇到這個問題,則可能需要考慮重新設計表或者應用,比如應用層面生成單調遞增的主鍵ID,插表不使用auto_increment機制,或者更改innodb_autonc_lock_mode配置。

主鍵隨機對聚簇索引的壞處

如果主鍵不是自增id,可以想象,它會幹些什麼,不斷地調整數據的物理地址、分頁,當然也有其他一些措施來減少這些操作。

例如從性能的角度考慮,使用UUID作爲聚簇索引會很糟糕:它使得聚簇索引的插入變得完全隨機,這是最壞的情況,使得數據沒有任何聚集特性。

而當採用UUID的聚簇索引的表往插入數據,如圖10所示,因爲新行的主鍵值不一定比之前的插入值大,所以InnoDB無法簡單的總是把新行插入到索引的最後,而是需要爲新的行尋找合適的位置----通常是已有數據的中間位置----並且分配空間。這會增加很多額外的工作,並導致數據分佈不夠優化。

總結使用UUID作爲主鍵的一些缺點:

  • 寫入目標頁可能已經刷到磁盤上並從緩存中移除,或者是還沒有被加載到緩存中,InnoDB在插入之前不得不先找到並從磁盤讀取目標頁到內存中,這將導致大量的隨機I/O;
  • 因爲寫入是亂序的,InnoDB不得不頻繁的做頁分裂操作,以便爲新的行分配空間。頁分裂會導致移動大量數據,一次插入最少需要修改三個頁而不是一個,包含兩個葉子節點和一個父節點。
  • 由於頻繁的頁分裂,頁會變得稀疏並被不規則的填充,所以最終數據會有碎片。

把這些隨機值載入到聚簇索引以後,需要做一次optimize table來重建表並優化頁的填充。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章