為什么MySQL索引要使用B+樹,而不是B樹议薪,紅黑樹

我們?cè)?a target="_blank">MySQL中的數(shù)據(jù)一般是放在磁盤中的尤蛮,讀取數(shù)據(jù)的時(shí)候肯定會(huì)有訪問(wèn)磁盤的操作,磁盤中有兩個(gè)機(jī)械運(yùn)動(dòng)的部分笙蒙,分別是盤片旋轉(zhuǎn)和磁臂移動(dòng)。盤片旋轉(zhuǎn)就是我們市面上所提到的多少轉(zhuǎn)每分鐘庆锦,而磁盤移動(dòng)則是在盤片旋轉(zhuǎn)到指定位置以后捅位,移動(dòng)磁臂后開始進(jìn)行數(shù)據(jù)的讀寫。那么這就存在一個(gè)定位到磁盤中的塊的過(guò)程搂抒,而定位是磁盤的存取中花費(fèi)時(shí)間比較大的一塊艇搀,畢竟機(jī)械運(yùn)動(dòng)花費(fèi)的時(shí)候要遠(yuǎn)遠(yuǎn)大于電子運(yùn)動(dòng)的時(shí)間。當(dāng)大規(guī)模數(shù)據(jù)存儲(chǔ)到磁盤中的時(shí)候求晶,顯然定位是一個(gè)非逞娴瘢花費(fèi)時(shí)間的過(guò)程,但是我們可以通過(guò)B樹進(jìn)行優(yōu)化芳杏,提高磁盤讀取時(shí)定位的效率矩屁。

為什么B類樹可以進(jìn)行優(yōu)化呢?我們可以根據(jù)B類樹的特點(diǎn)爵赵,構(gòu)造一個(gè)多階的B類樹吝秕,然后在盡量多的在結(jié)點(diǎn)上存儲(chǔ)相關(guān)的信息,保證層數(shù)(樹的高度)盡量的少空幻,以便后面我們可以更快的找到信息烁峭,磁盤的I/O操作也少一些,而且B類樹是平衡樹秕铛,每個(gè)結(jié)點(diǎn)到葉子結(jié)點(diǎn)的高度都是相同约郁,這也保證了每個(gè)查詢是穩(wěn)定的。

特別地:只有B-樹和B+樹但两,這里的B-樹是叫B樹鬓梅,不是B減樹。沒(méi)有B減樹的谨湘。

以下摘自【程序員小灰】

什么是B樹

一個(gè)m階的B樹具有如下幾個(gè)特征:

1姥宝、根結(jié)點(diǎn)至少有兩個(gè)子女。 2凳忙、每個(gè)中間節(jié)點(diǎn)都包含k-1個(gè)元素和k個(gè)孩子氧急,其中 m/2 <= k <= m 3、每一個(gè)葉子節(jié)點(diǎn)都包含k-1個(gè)元素欧募,其中 m/2 <= k <= m 4、所有的葉子結(jié)點(diǎn)都位于同一層。5赤拒、每個(gè)節(jié)點(diǎn)中的元素從小到大排列,節(jié)點(diǎn)當(dāng)中k-1個(gè)元素正好是k個(gè)孩子包含的元素的值域分劃诱鞠。

下面以3階B樹開始學(xué)習(xí)

這棵樹中挎挖,重點(diǎn)看(2,6)節(jié)點(diǎn)。該節(jié)點(diǎn)有兩個(gè)元素2和6航夺,又有三個(gè)孩子1蕉朵,(3,5),8阳掐。其中1小于元素2始衅,(3,5)在(2,6)之間缭保,8大于(3,5)汛闸,正好符合上面所列的特征。

B樹查詢的流程:

比如上面的3階B樹查詢數(shù)值5艺骂。

第1次IO:

第2次IO:


第3次IO:

第3次內(nèi)存比較:

總結(jié):每次深度加1就會(huì)進(jìn)行一次磁盤IO的查詢诸老,將當(dāng)前高度的數(shù)據(jù)加到內(nèi)存中,再進(jìn)行數(shù)值比較钳恕。從中可以看出相比大部分的查詢時(shí)間是花費(fèi)在磁盤IO的速度上别伏,所以要想提高性能就是將樹的高度足夠低,IO次數(shù)足夠少忧额,這就是B樹的優(yōu)勢(shì)畸肆。

B樹添加的流程:

比如樹里添加數(shù)值4 自頂向下查找4的節(jié)點(diǎn)位置,發(fā)現(xiàn)4應(yīng)當(dāng)插入到節(jié)點(diǎn)元素3宙址,5之間

節(jié)點(diǎn)3轴脐,5已經(jīng)是兩元素節(jié)點(diǎn),無(wú)法再增加抡砂。父親節(jié)點(diǎn) 2大咱, 6 也是兩元素節(jié)點(diǎn),也無(wú)法再增加注益。根節(jié)點(diǎn)9是單元素節(jié)點(diǎn)碴巾,可以升級(jí)為兩元素節(jié)點(diǎn)。于是拆分節(jié)點(diǎn)3丑搔,5與節(jié)點(diǎn)2厦瓢,6提揍,讓根節(jié)點(diǎn)9升級(jí)為兩元素節(jié)點(diǎn)4,9煮仇。節(jié)點(diǎn)6獨(dú)立為根節(jié)點(diǎn)的第二個(gè)孩子劳跃。

從圖中可以看到,為了插入一個(gè)元素浙垫,幾乎全部的位置都變化了刨仑,這就是B樹的自平衡(始終維持多路平衡)。

B樹刪除的流程:

自頂向下查找元素11的節(jié)點(diǎn)位置夹姥。

刪除11后杉武,節(jié)點(diǎn)12只有一個(gè)孩子,不符合B樹規(guī)范辙售。因此找出12,13,15三個(gè)節(jié)點(diǎn)的中位數(shù)13轻抱,取代節(jié)點(diǎn)12,而節(jié)點(diǎn)12自身下移成為第一個(gè)孩子旦部。(這個(gè)過(guò)程稱為左旋)

B樹應(yīng)用

主要用于文件系統(tǒng)以及部分?jǐn)?shù)據(jù)庫(kù)索引(MongoDB) 而Mysql是用B+樹的祈搜。

什么是B+樹

一個(gè)m階的B+樹具有如下幾個(gè)特征:

1、有k個(gè)子樹的中間節(jié)點(diǎn)包含有k個(gè)元素(B樹中是k-1個(gè)元素)志鹃,每個(gè)元素不保存數(shù)據(jù)夭问,只用來(lái)索引泽西,所有數(shù)據(jù)都保存在葉子節(jié)點(diǎn)曹铃。 2、所有的葉子結(jié)點(diǎn)中包含了全部元素的信息捧杉,及指向含這些元素記錄的指針陕见,且葉子結(jié)點(diǎn)本身依關(guān)鍵字的大小自小而大順序鏈接。 3味抖、所有的中間節(jié)點(diǎn)元素都同時(shí)存在于子節(jié)點(diǎn)评甜,在子節(jié)點(diǎn)元素中是最大(或最小)元素仔涩。

從上圖可以發(fā)現(xiàn)每一個(gè)父節(jié)點(diǎn)的元素都出現(xiàn)在子節(jié)點(diǎn)中忍坷,并且是子節(jié)點(diǎn)的最大(或最小)

從圖中可以看到根節(jié)點(diǎn)元素8是字節(jié)點(diǎn)2,5,8的最大元素熔脂,也是葉子節(jié)點(diǎn)6佩研,8的最大元素。根節(jié)點(diǎn)15是子節(jié)點(diǎn)11,15的最大元素霞揉,也是葉子節(jié)點(diǎn)13,15的最大元素旬薯。

B+樹的最大元素始終位于根節(jié)點(diǎn)當(dāng)中。所有葉子節(jié)點(diǎn)包含了全量元素信息适秩,并且每一個(gè)葉子節(jié)點(diǎn)都帶有指向 下一個(gè)節(jié)點(diǎn)指針绊序,形成了一個(gè)有序鏈表硕舆。

B+樹查詢流程

單個(gè)查詢:查詢某個(gè)元素3

第一次磁盤IO:

第二次磁盤IO:

第三次磁盤IO:

這樣看起來(lái)跟B樹沒(méi)有什么區(qū)別。但其實(shí)有兩點(diǎn)是需要注意的:

1骤公、B+樹的中間節(jié)點(diǎn)沒(méi)有衛(wèi)星數(shù)據(jù)的抚官。所以同樣大小的磁盤頁(yè)可以容納更多的節(jié)點(diǎn)元素。(這就意味著B+會(huì)更加矮胖淋样,查詢的IO次數(shù)會(huì)更少)

B樹的衛(wèi)星數(shù)據(jù)

B+樹的衛(wèi)星數(shù)據(jù)

2耗式、B樹查找性能是不穩(wěn)定的(如果要查找的數(shù)據(jù)分別在根節(jié)點(diǎn)和葉子節(jié)點(diǎn),他們的性能就會(huì)不同)趁猴。但B+樹的每一次都是穩(wěn)定的刊咳,為啥呢,看下面的范圍查詢儡司。

范圍查詢:查找到范圍的下限(3)

B樹的范圍查詢:

自頂向下娱挨,查找到范圍的下限(3),最多6條:

中序遍歷到元素6:

中序遍歷到元素8:

中序遍歷到元素9:

中序遍歷到元素11捕犬,遍歷結(jié)束:

B+樹的范圍查詢:

自頂向下跷坝,查找到范圍的下限(3),最多6條:

通過(guò)鏈表指針碉碉,遍歷到元素6, 8:

通過(guò)鏈表指針柴钻,遍歷到元素9, 11,遍歷結(jié)束:

從上面的流程比較垢粮,可以得出以下B+樹的優(yōu)勢(shì):

1.單一節(jié)點(diǎn)存儲(chǔ)更多的元素贴届,使得查詢的IO次數(shù)更少。

2.所有查詢都要查找到葉子節(jié)點(diǎn)蜡吧,查詢性能穩(wěn)定毫蚓。

3.所有葉子節(jié)點(diǎn)形成有序鏈表,便于范圍查詢昔善。

面試題

問(wèn)題1:MySQL中存儲(chǔ)索引用到的數(shù)據(jù)結(jié)構(gòu)是B+樹元潘,B+樹的查詢時(shí)間跟樹的高度有關(guān),是log(n)君仆,如果用hash存儲(chǔ)翩概,那么查詢時(shí)間是O(1)。既然hash比B+樹更快返咱,為什么mysql用B+樹來(lái)存儲(chǔ)索引呢钥庇?

答:一、從內(nèi)存角度上說(shuō)洛姑,數(shù)據(jù)庫(kù)中的索引一般時(shí)在磁盤上上沐,數(shù)據(jù)量大的情況可能無(wú)法一次性裝入內(nèi)存,B+樹的設(shè)計(jì)可以允許數(shù)據(jù)分批加載楞艾。

二参咙、從業(yè)務(wù)場(chǎng)景上說(shuō)龄广,如果只選擇一個(gè)數(shù)據(jù)那確實(shí)是hash更快,但是數(shù)據(jù)庫(kù)中經(jīng)常會(huì)選中多條這時(shí)候由于B+樹索引有序蕴侧,并且又有鏈表相連择同,它的查詢效率比hash就快很多了。

問(wèn)題2:為什么不用紅黑樹或者二叉排序樹净宵?

答:樹的查詢時(shí)間跟樹的高度有關(guān)敲才,B+樹是一棵多路搜索樹可以降低樹的高度,提高查找效率

問(wèn)題3:既然增加樹的路數(shù)可以降低樹的高度择葡,那么無(wú)限增加樹的路數(shù)是不是可以有最優(yōu)的查找效率紧武?

答:這樣會(huì)形成一個(gè)有序數(shù)組,文件系統(tǒng)和數(shù)據(jù)庫(kù)的索引都是存在硬盤上的敏储,并且如果數(shù)據(jù)量大的話阻星,不一定能一次性加載到內(nèi)存中。有序數(shù)組沒(méi)法一次性加載進(jìn)內(nèi)存已添,這時(shí)候B+樹的多路存儲(chǔ)威力就出來(lái)了妥箕,可以每次加載B+樹的一個(gè)結(jié)點(diǎn),然后一步步往下找更舞,

問(wèn)題4:在內(nèi)存中畦幢,紅黑樹比B樹更優(yōu),但是涉及到磁盤操作B樹就更優(yōu)了缆蝉,那么你能講講B+樹嗎宇葱?

B+樹是在B樹的基礎(chǔ)上進(jìn)行改造,它的數(shù)據(jù)都在葉子結(jié)點(diǎn)返奉,同時(shí)葉子結(jié)點(diǎn)之間還加了指針形成鏈表贝搁。

下面是一個(gè)4路B+樹吗氏,它的數(shù)據(jù)都在葉子結(jié)點(diǎn)芽偏,并且有鏈表相連。

問(wèn)題5:為什么B+樹要這樣設(shè)計(jì)弦讽?

答:這個(gè)跟它的使用場(chǎng)景有關(guān)污尉,B+樹在數(shù)據(jù)庫(kù)的索引中用得比較多,數(shù)據(jù)庫(kù)中select數(shù)據(jù)往产,不一定只選一條被碗,很多時(shí)候會(huì)選中多條,比如按照id進(jìn)行排序后選100條仿村。如果是多條的話锐朴,B+樹需要做局部的中序遍歷,可能要跨層訪問(wèn)蔼囊。而B+樹由于所有數(shù)據(jù)都在葉子結(jié)點(diǎn)不用跨層焚志,同時(shí)由于有鏈表結(jié)構(gòu)衣迷,只需要找到首尾,通過(guò)鏈表就能把所有數(shù)據(jù)取出來(lái)了酱酬。

比如選出7到19只需要在葉子結(jié)點(diǎn)中就能找到壶谒。

數(shù)據(jù)庫(kù)索引為什么要用 B+ 樹而不用紅黑樹呢?

AVL 樹和紅黑樹這些二叉樹結(jié)構(gòu)的數(shù)據(jù)結(jié)構(gòu)可以達(dá)到最高的查詢效率這是毋庸置疑的膳沽。

既然如此汗菜,那么數(shù)據(jù)庫(kù)索引為什么不用 AVL 樹或者紅黑樹呢?

這就牽扯到一個(gè)問(wèn)題了挑社,不考慮每種數(shù)據(jù)結(jié)構(gòu)的前提條件而選擇數(shù)據(jù)結(jié)構(gòu)都是在耍流氓陨界。

AVL 數(shù)和紅黑樹基本都是存儲(chǔ)在內(nèi)存中才會(huì)使用的數(shù)據(jù)結(jié)構(gòu),那磁盤中會(huì)有什么不同呢痛阻?

這就要牽扯到磁盤的存儲(chǔ)原理了

操作系統(tǒng)讀寫磁盤的基本單位是扇區(qū)普碎,而文件系統(tǒng)的基本單位是簇(Cluster)。

也就是說(shuō)录平,磁盤讀寫有一個(gè)最少內(nèi)容的限制麻车,即使我們只需要這個(gè)簇上的一個(gè)字節(jié)的內(nèi)容,我們也要含著淚把一整個(gè)簇上的內(nèi)容讀完斗这。

那么动猬,現(xiàn)在問(wèn)題就來(lái)了

一個(gè)父節(jié)點(diǎn)只有 2 個(gè)子節(jié)點(diǎn),并不能填滿一個(gè)簇上的所有內(nèi)容氨砑赁咙?那多余的內(nèi)容豈不是要浪費(fèi)了?我們?cè)趺床拍馨牙速M(fèi)的這部分內(nèi)容利用起來(lái)呢免钻?哈哈彼水,答案就是 B+ 樹。

由于 B+ 樹分支比二叉樹更多极舔,所以相同數(shù)量的內(nèi)容凤覆,B+ 樹的深度更淺,深度代表什么拆魏?代表磁盤 io 次數(shù)岸㈣搿!數(shù)據(jù)庫(kù)設(shè)計(jì)的時(shí)候 B+ 樹有多少個(gè)分支都是按照磁盤一個(gè)簇上最多能放多少節(jié)點(diǎn)設(shè)計(jì)的安橙小拥峦!

所以,涉及到磁盤上查詢的數(shù)據(jù)結(jié)構(gòu)卖子,一般都用 B+ 樹啦略号。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子玄柠,更是在濱河造成了極大的恐慌氛琢,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,122評(píng)論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件随闪,死亡現(xiàn)場(chǎng)離奇詭異阳似,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)铐伴,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,070評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門撮奏,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人当宴,你說(shuō)我怎么就攤上這事畜吊。” “怎么了户矢?”我有些...
    開封第一講書人閱讀 164,491評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵玲献,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我梯浪,道長(zhǎng)捌年,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,636評(píng)論 1 293
  • 正文 為了忘掉前任挂洛,我火速辦了婚禮礼预,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘虏劲。我一直安慰自己托酸,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,676評(píng)論 6 392
  • 文/花漫 我一把揭開白布柒巫。 她就那樣靜靜地躺著励堡,像睡著了一般。 火紅的嫁衣襯著肌膚如雪堡掏。 梳的紋絲不亂的頭發(fā)上应结,一...
    開封第一講書人閱讀 51,541評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音布疼,去河邊找鬼摊趾。 笑死币狠,一個(gè)胖子當(dāng)著我的面吹牛游两,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播漩绵,決...
    沈念sama閱讀 40,292評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼贱案,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起宝踪,我...
    開封第一講書人閱讀 39,211評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤侨糟,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后瘩燥,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體秕重,經(jīng)...
    沈念sama閱讀 45,655評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,846評(píng)論 3 336
  • 正文 我和宋清朗相戀三年厉膀,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了溶耘。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,965評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡服鹅,死狀恐怖凳兵,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情企软,我是刑警寧澤庐扫,帶...
    沈念sama閱讀 35,684評(píng)論 5 347
  • 正文 年R本政府宣布,位于F島的核電站仗哨,受9級(jí)特大地震影響形庭,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜厌漂,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,295評(píng)論 3 329
  • 文/蒙蒙 一碘勉、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧桩卵,春花似錦验靡、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,894評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至钩乍,卻和暖如春辞州,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背寥粹。 一陣腳步聲響...
    開封第一講書人閱讀 33,012評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工变过, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人涝涤。 一個(gè)月前我還...
    沈念sama閱讀 48,126評(píng)論 3 370
  • 正文 我出身青樓媚狰,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親阔拳。 傳聞我的和親對(duì)象是個(gè)殘疾皇子崭孤,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,914評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • 他喜歡她很久很久,但不敢說(shuō)出來(lái)嗤形。愚人節(jié)的時(shí)候精偿,他借著這樣的機(jī)會(huì)在人群面前大聲地對(duì)她喊:“我喜歡你「潮”然而他并...
    杯子屋閱讀 254評(píng)論 0 1
  • 一直很向往去國(guó)外旅游还最,也想不明白是為什么?也許是去到國(guó)外后毡惜,國(guó)內(nèi)的一切可以暫時(shí)逃避了拓轻?也許是羨慕外國(guó)人講一口流利的...
    EugeniaYu閱讀 236評(píng)論 0 0
  • 不論是棒打鴛鴦扶叉,還是逼嫁逼婚,父母在兒女的婚姻大事上操碎了心帕膜。我想對(duì)于那些瀕臨絕望的父母枣氧,產(chǎn)生“逼婚難,難于再給你...
    西召閱讀 194評(píng)論 0 1