2014阿裡實習生面試題——mysql如何實現索引的

這是2014阿裡實習生北京站二面的一道試題:

在MySQL中,索引屬於存儲引擎級別的概念,不同存儲引擎對索引的實現方式是不同的,比如MyISAM和InnoDB存儲引擎。

MyISAM索引實現:

MyISAM存儲引擎使用B+Tree作為索引結構,葉節點的data域存放的是數據記錄的地址。MyISAM的索引方式也叫做“非Ju集”的,之所以這麼稱呼是為瞭與InnoDB的ju集索引區分。

InnoDB索引實現:

雖然InnoDB也使用B+Tree作為索引結構,但具體實現方式卻與MyISAM截然不同。

第一個重大區別是:InnoDB的數據文件本身就是索引文件。

第二個與MyISAM索引的不同是:InnoDB的輔助索引data域存儲相應記錄主鍵的值而不是地址。ju集索引這種實現方式使得按主鍵的搜尋十分高效,但是輔助索引搜尋需要檢索兩遍索引:首先檢索輔助索引獲得主鍵,然後用主鍵到主索引中檢索獲得記錄。

其實,資料庫索引的實現可以采用紅黑樹,B-Tree樹數據結構。

但是為什麼實際上采用的B+Tree呢?

這要從計算機存儲原理和操作系統相關知識說起。因為數據表的索引比較大,不能常駐內存,所以以文件形式存儲在磁盤中。所以當查詢數據的時候就需要I/O操作。高效率查詢的目標是較少I/O次數。一次I/O一般讀取一頁(一般為4k)大小的數據(局部性原理)。如此,在B-樹中,每當申請一個新結點時,就以頁的大小來申請。也就是說一次I/o可以讀取一個一個結點(包含很多key)的數據;而在紅黑樹結構結構中,邏輯相鄰的結點物理上不一定相鄰,就是說,讀取同等的數據需要多次I/O。所以選擇B-樹效率更好。

那為何最終選瞭B+樹呢?

因為B+樹內節點去掉瞭data域,因此可以擁有更大的出度,就是說一個結點可以存儲更多的內結點,那麼I/O效率更高。

瞭解不同存儲引擎的索引實現方式對於正確使用和優化索引都非常有幫助,例如知道瞭InnoDB的索引實現後,就很容易明白為什麼不建議使用過長的字段作為主鍵,因為所有輔助索引都引用主索引,過長的主索引會令輔助索引變得過大。再例如,用非單調的字段作為主鍵在InnoDB中不是個好主意,因為InnoDB數據文件本身是一顆B+Tree,非單調的主鍵會造成在插入新記錄時數據文件為瞭維持B+Tree的特性而頻繁的分裂調整,十分低效,而使用自增字段作為主鍵則是一個很好的選擇。

ju集索引與非ju集索引之分:

InnoDB是ju集索引,因為它的B+樹的葉結點包含瞭完整的數據記錄。而MyISAM方式B+樹的葉結點隻是存儲瞭數據的地址,故稱為非ju集索引。

索引使用策略及優化

MySQL的優化主要分為結構優化(Scheme optimization)和查詢優化(Query optimization)。詳情查看此文:

《MySQL索引背後的數據結構及算法原理》

註:聚,都用ju代替,ju集居然是敏感詞,太坑瞭,求破解方法

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *