【數據庫】淺析Innodb的聚集索引與非聚集索引

Mysql存儲引擎之一的Innodb的索引,可以分爲聚集索引與非聚集索引,這兩種索引都是使用B+樹組織的。

本文不講解什麼是索引,對索引不瞭解的同學可以先移步到我的另外一篇文章【數據庫】mysql索引簡談

在分析這兩種索引之前,我們先建立一個Person表:

CREATE TABLE person  (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '自增主鍵',
  `name` varchar(255) COMMENT '姓名',
  `age` int(11) COMMENT '年齡',
  PRIMARY KEY (`id`),
  KEY(`name`)
) ENGINE = InnoDB;

其中id爲主鍵,name爲普通索引。

這是其中的部分數據:


假設我現在需要查找id=5的記錄,按照正常邏輯,需要去遍歷該表中所有的數據。在最壞的情況下,需要遍歷5次才能取到數據,時間複雜度爲O(N)。正常的表中會有幾萬、幾十萬條數據,使用這種遍歷的方法的話,那業務別做了,公司別開了,倒閉算了。

使用索引後,會將表中的記錄按照某種規則轉換爲平衡樹結構,大大減少查詢的次數,具體是什麼結構,取決於建立的索引的類型。

聚集索引:

聚集索引,也成聚簇索引,一般情況下,指定id爲主鍵,就會生成一個以id爲基礎的聚集索引。

在聚集索引的樹結構中,所有節點都會存儲主鍵值,而葉子節點還會多存儲主鍵對應的行記錄

此外,真實的數據行會按照主鍵排序,順序存儲在磁盤上,比如id爲1和2的對應記錄在磁盤上相鄰存儲。

一張表只有一個主鍵,因此一個表只有一個聚集索引。

 

非聚集索引:

非聚集索引,也是一顆平衡樹。所有節點都會存儲索引列的值,比如這裏就是name列的值,葉子節點還會多存儲該name值所對應的的聚集索引的值,即主鍵的值

不同於聚集索引,真實的數據行不會按照非聚集索引排序存儲,但索引項的內容是按順序存儲的。

一個表可以有多個非主鍵索引,因此會建立多個非聚集索引,每建立一個非聚集索引,都會將該非聚集索引關聯的字段數據複製出來一份,用於生成以該列爲基礎的平衡樹。這樣的操作會增加表的體積,佔用磁盤空間,所以不是索引越多越好。

通過非聚集索引查詢數據時,查詢到葉子節點上的主鍵值後,再利用這個主鍵值查詢聚集索引,從而查詢到具體的行記錄,這個需要遍歷兩次樹。


所以,不管以任何方式查詢數據,最後都會利用聚集索引查詢數據,在我們之前定義的表中,聚集索引是通往真實記錄的唯一大道。

但所謂條條大路通羅馬,我們稍微改變表的結構就可以,只需要建立一個組合索引,包括name和age字段

那麼,當我們執行這條語句時:

select age from person where name='cc';

由於建立的是組合索引,因此每個葉子節點存儲的是name和age兩個字段的值,以及主鍵id的值。由於此時已經有age值,直接返回即可,此時不需要再通過這個主鍵id查詢聚集索引。

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