面試官:小夥子,你給我說一下你對MySQL索引的理解吧

1、索引是什麼?

索引是幫助MySQL高效獲取數據的數據結構。mysql

2、索引能幹什麼?

索引很是關鍵,尤爲是當表中的數據量愈來愈大時,索引對於性能的影響愈發重要。索引可以輕易將查詢性能提升好幾個數量級,總的來講就是能夠明顯的提升查詢效率。sql

3、索引的分類?

一、從存儲結構上來劃分:BTree索引(B-Tree或B+Tree索引),Hash索引,full-index全文索引,R-Tree索引。這裏所描述的是索引存儲時保存的形式,數據庫

二、從應用層次來分:普通索引,惟一索引,複合索引數據結構

三、根據中數據的物理順序與鍵值的邏輯(索引)順序關係:彙集索引,非彙集索引。性能

平時講的索引類型通常是指在應用層次的劃分。spa

就像手機分類:安卓手機,IOS手機 與 華爲手機,蘋果手機,OPPO手機同樣。3d

普通索引:即一個索引只包含單個列,一個表能夠有多個單列索引指針

惟一索引:索引列的值必須惟一,但容許有空值code

複合索引:多列值組成一個索引,專門用於組合搜索,其效率大於索引合併blog

聚簇索引(彙集索引):並非一種單獨的索引類型,而是一種數據存儲方式。具體細節取決於不一樣的實現,InnoDB的聚簇索引其實就是在同一個結構中保存了B-Tree索引(技術上來講是B+Tree)和數據行。

非聚簇索引:不是聚簇索引,就是非聚簇索引

4、索引的底層實現

mysql默認存儲引擎innodb只顯式支持B-Tree( 從技術上來講是B+Tree)索引,對於頻繁訪問的表,innodb會透明創建自適應hash索引,即在B樹索引基礎上創建hash索引,能夠顯著提升查找效率,對於客戶端是透明的,不可控制的,隱式的。

不談存儲引擎,只討論實現(抽象)

4.一、Hash索引

基於哈希表實現,只有精確匹配索引全部列的查詢纔有效,對於每一行數據,存儲引擎都會對全部的索引列計算一個哈希碼(hash code),而且Hash索引將全部的哈希碼存儲在索引中,同時在索引表中保存指向每一個數據行的指針。

4.二、B-Tree索引(MySQL使用B+Tree)

B-Tree能加快數據的訪問速度,由於存儲引擎再也不須要進行全表掃描來獲取數據,數據分佈在各個節點之中。

4.三、B+Tree索引

是B-Tree的改進版本,同時也是數據庫索引索引所採用的存儲結構。數據都在葉子節點上,而且增長了順序訪問指針,每一個葉子節點都指向相鄰的葉子節點的地址。相比B-Tree來講,進行範圍查找時只須要查找兩個節點,進行遍歷便可。而B-Tree須要獲取全部節點,相比之下B+Tree效率更高。

結合存儲引擎來討論(通常默認使用B+Tree)

案例:假設有一張學生表,id爲主鍵

id name birthday
1 Tom 1996-01-01
2 Jann 1996-01-04
3 Ray 1996-01-08
4 Michael 1996-01-10
5 Jack 1996-01-13
6 Steven 1996-01-23
7 Lily 1996-01-25

在MyISAM引擎中的實現(二級索引也是這樣實現的)

在InnoDB中的實現

5、爲何索引結構默認使用B+Tree,而不是Hash,二叉樹,紅黑樹?

B-tree:由於B樹無論葉子節點仍是非葉子節點,都會保存數據,這樣致使在非葉子節點中能保存的指針數量變少(有些資料也稱爲扇出),指針少的狀況下要保存大量數據,只能增長樹的高度,致使IO操做變多,查詢性能變低;

Hash:雖然能夠快速定位,可是沒有順序,IO複雜度高。

二叉樹:樹的高度不均勻,不能自平衡,查找效率跟數據有關(樹的高度),而且IO代價高。

紅黑樹:樹的高度隨着數據量增長而增長,IO代價高。

6、爲何官方建議使用自增加主鍵做爲索引?

結合B+Tree的特色,自增主鍵是連續的,在插入過程當中儘可能減小頁分裂,即便要進行頁分裂,也只會分裂不多一部分。而且能減小數據的移動,每次插入都是插入到最後。總之就是減小分裂和移動的頻率。

6.一、插入連續的數據:

6.二、插入非連續的數據:

7、簡單總結下

一、MySQL使用B+Tree做爲索引數據結構。

二、B+Tree在新增數據時,會根據索引指定列的值對舊的B+Tree作調整。三、從物理存儲結構上說,B-Tree和B+Tree都以頁(4K)來劃分節點的大小,可是因爲B+Tree中中間節點不存儲數據,所以B+Tree可以在一樣大小的節點中,存儲更多的key,提升查找效率。四、影響MySQL查找性能的主要仍是磁盤IO次數,大部分是磁頭移動到指定磁道的時間花費。五、MyISAM存儲引擎下索引和數據存儲是分離的,InnoDB索引和數據存儲在一塊兒。六、InnoDB存儲引擎下索引的實現,(輔助索引)所有是依賴於主索引創建的(輔助索引中葉子結點存儲的並非數據的地址,仍是主索引的值,所以,全部依賴於輔助索引的都是先根據輔助索引查到主索引,再根據主索引查數據的地址)。

八、因爲InnoDB索引的特性,所以若是主索引不是自增的(id做主鍵),那麼每次插入新的數據,都極可能對B+Tree的主索引進行重整,影響性能。所以,儘可能以自增id做爲InnoDB的主索引。

相關文章
相關標籤/搜索