1. 程式人生 > >淺談聚簇索引和非聚簇索引的區別

淺談聚簇索引和非聚簇索引的區別

聚簇索引:將資料儲存與索引放到了一塊,索引結構的葉子節點儲存了行資料

非聚簇索引:將資料與索引分開儲存,索引結構的葉子節點指向了資料對應的位置

 

在innodb中,在聚簇索引之上建立的索引稱之為輔助索引,非聚簇索引都是輔助索引,像複合索引、字首索引、唯一索引。輔助索引葉子節點儲存的不再是行的物理位置,而是主鍵值,輔助索引訪問資料總是需要二次查詢

  1. InnoDB使用的是聚簇索引,將主鍵組織到一棵B+樹中,而行資料就儲存在葉子節點上,若使用"where id = 14"這樣的條件查詢主鍵,則按照B+樹的檢索演算法即可查詢到對應的葉節點,之後獲得行資料。
  2. 若對Name列進行條件搜尋,則需要兩個步驟:第一步在輔助索引B+樹中檢索Name,到達其葉子節點獲取對應的主鍵。第二步使用主鍵在主索引B+樹種再執行一次B+樹檢索操作,最終到達葉子節點即可獲取整行資料。(重點在於通過其他鍵需要建立輔助索引)

 

聚簇索引具有唯一性,由於聚簇索引是將資料跟索引結構放到一塊,因此一個表僅有一個聚簇索引。

聚簇索引預設是主鍵,如果表中沒有定義主鍵,InnoDB 會選擇一個唯一且非空的索引代替。如果沒有這樣的索引,InnoDB 會隱式定義一個主鍵(類似oracle中的RowId)來作為聚簇索引。如果已經設定了主鍵為聚簇索引又希望再單獨設定聚簇索引,必須先刪除主鍵,然後新增我們想要的聚簇索引,最後恢復設定主鍵即可。

 

MyISAM使用的是非聚簇索引,非聚簇索引的兩棵B+樹看上去沒什麼不同,節點的結構完全一致只是儲存的內容不同而已,主鍵索引B+樹的節點儲存了主鍵,輔助鍵索引B+樹儲存了輔助鍵。表資料儲存在獨立的地方,這兩顆B+樹的葉子節點都使用一個地址指向真正的表資料,對於表資料來說,這兩個鍵沒有任何差別。由於索引樹是獨立的,通過輔助鍵檢索無需訪問主鍵的索引樹

使用聚簇索引的優勢:

每次使用輔助索引檢索都要經過兩次B+樹查詢,看上去聚簇索引的效率明顯要低於非聚簇索引,這不是多此一舉嗎?聚簇索引的優勢在哪?

1.由於行資料和聚簇索引的葉子節點儲存在一起,同一頁中會有多條行資料,訪問同一資料頁不同行記錄時,已經把頁載入到了Buffer中(快取器),再次訪問時,會在記憶體中完成訪問,不必訪問磁碟。這樣主鍵和行資料是一起被載入記憶體的,找到葉子節點就可以立刻將行資料返回了,如果按照主鍵Id來組織資料,獲得資料更快。

2.輔助索引的葉子節點,儲存主鍵值,而不是資料的存放地址。好處是當行資料放生變化時,索引樹的節點也需要分裂變化;或者是我們需要查詢的資料,在上一次IO讀寫的快取中沒有,需要發生一次新的IO操作時,可以避免對輔助索引的維護工作,只需要維護聚簇索引樹就好了。另一個好處是,因為輔助索引存放的是主鍵值,減少了輔助索引佔用的儲存空間大小。

注:我們知道一次io讀寫,可以獲取到16K大小的資源,我們稱之為讀取到的資料區域為Page。而我們的B樹,B+樹的索引結構,葉子節點上存放好多個關鍵字(索引值)和對應的資料,都會在一次IO操作中被讀取到快取中,所以在訪問同一個頁中的不同記錄時,會在記憶體裡操作,而不用再次進行IO操作了。除非發生了頁的分裂,即要查詢的行資料不在上次IO操作的換村裡,才會觸發新的IO操作。

3.因為MyISAM的主索引並非聚簇索引,那麼他的資料的實體地址必然是凌亂的,拿到這些實體地址,按照合適的演算法進行I/O讀取,於是開始不停的尋道不停的旋轉。聚簇索引則只需一次I/O。(強烈的對比)

4.不過,如果涉及到大資料量的排序、全表掃描、count之類的操作的話,還是MyISAM佔優勢些,因為索引所佔空間小,這些操作是需要在記憶體中完成的。

 

聚簇索引需要注意的地方

當使用主鍵為聚簇索引時,主鍵最好不要使用uuid,因為uuid的值太過離散,不適合排序且可能出線新增加記錄的uuid,會插入在索引樹中間的位置,導致索引樹調整複雜度變大,消耗更多的時間和資源。

建議使用int型別的自增,方便排序並且預設會在索引樹的末尾增加主鍵值,對索引樹的結構影響最小。而且,主鍵值佔用的儲存空間越大,輔助索引中儲存的主鍵值也會跟著變大,佔用儲存空間,也會影響到IO操作讀取到的資料量。

為什麼主鍵通常建議使用自增id

聚簇索引的資料的物理存放順序與索引順序是一致的,即:只要索引是相鄰的,那麼對應的資料一定也是相鄰地存放在磁碟上的。如果主鍵不是自增id,那麼可以想 象,它會幹些什麼,不斷地調整資料的實體地址、分頁,當然也有其他一些措施來減少這些操作,但卻無法徹底避免。但,如果是自增的,那就簡單了,它只需要一 頁一頁地寫,索引結構相對緊湊,磁碟碎片少,效率也高。

 

轉載:

https://www.jianshu.c