深入理解mysql索引底層數(shù)據(jù)結(jié)構(gòu)與算法

索引到底是什么

索引是幫助Mysql高效獲取數(shù)據(jù)的一種數(shù)據(jù)結(jié)構(gòu)

索引儲存在哪里

和數(shù)據(jù)一樣饱溢,索引以文件形式儲存在硬盤上牧抵,在MyISAM儲存引擎中,數(shù)據(jù)和索引文件試試分開儲存的。


MyISAM文件儲存示意圖

在InnoDB中碳褒,數(shù)據(jù)和索引文件是合起來儲存的,注意下圖中沒有了I(index)結(jié)尾的文件看疗。


InnoDB文件儲存示意圖

后面會進(jìn)一步分析為什么會這樣

索引的數(shù)據(jù)結(jié)構(gòu)

想想JDK8的Hashmap中沙峻,當(dāng)鏈表長度大于一定限度時(shí),為了能夠高效的檢索數(shù)據(jù)两芳,引入了紅黑樹摔寨。索引的思想也是這樣,通過一種數(shù)據(jù)結(jié)構(gòu)高效的數(shù)據(jù)結(jié)構(gòu)來加速數(shù)據(jù)檢索的過程怖辆。
想想以下這幾種常用的數(shù)據(jù)結(jié)構(gòu)可否用于索引呢是复?
1. BST
2. 紅黑樹
3. Hash

BST在節(jié)點(diǎn)有序的情況下會變成一種線性結(jié)構(gòu),復(fù)雜度退化到O(n)竖螃,顯然是不行的淑廊。
紅黑樹解決了平衡的問題,但是在數(shù)據(jù)量比較大的情況下特咆,紅黑樹的高度太高季惩,導(dǎo)致磁盤IO次數(shù)過多,也不夠合理坚弱。
Hash似乎解決了磁盤IO的問題蜀备,但是Hash有大量沖突的時(shí)候還是線性遍歷,最關(guān)鍵的是限制太多荒叶,例如無法支持范圍查詢碾阁,也不支持部分索引匹配。

B+樹

B-樹
B+樹

比起紅黑樹些楣,上面兩種數(shù)據(jù)結(jié)構(gòu)都更加矮胖脂凶。他們兩之間一個(gè)很大的不同是B+樹的節(jié)點(diǎn)上不儲存value宪睹,只儲存key,而葉子節(jié)點(diǎn)上儲存了所有kv集合蚕钦,并且節(jié)點(diǎn)之間都是有序的亭病。

這樣的好處是每一次磁盤IO能夠讀取的節(jié)點(diǎn)更多,也就是樹的度可以設(shè)置的更大一些嘶居,因?yàn)槊看未疟PIO讀取的磁盤頁數(shù)是一定的罪帖,例如每次磁盤IO能夠讀取1頁=4kb,那么省去value的情況下同樣一頁數(shù)據(jù)能夠讀取更多的key整袁,這樣就大大減少了磁盤的IO次數(shù)。

此外佑吝,B+樹是排序好的數(shù)據(jù)結(jié)構(gòu),數(shù)據(jù)庫中><或者order by等都可以直接依賴這一特性芋忿。

MyISAM索引實(shí)現(xiàn)(非聚集索引)

MyISAM中索引和數(shù)據(jù)是分開儲存的,并且主鍵索引和輔助索引(二級索引)的儲存方式是一樣的戈钢。


主鍵索引
輔助索引

InnoDB索引實(shí)現(xiàn)(聚集索引)

InnoDB中索引文件和數(shù)據(jù)文件是同一個(gè)文件。并且主鍵索引和二級索引儲存方式有所不同殉了,如圖所示,二級索引的葉子節(jié)點(diǎn)不儲存數(shù)據(jù)宣渗,僅儲存主鍵ID梨州。


主鍵索引
輔助索引

這里思考兩個(gè)問題

  1. InnoDB表中必然有主鍵,為什么最好一定是有序自增id暴匠?
  2. 為什么二級索引葉子節(jié)點(diǎn)儲存的是主鍵值鞍恢?

問題一:如果id是無序的,那么很有可能新插入的值會導(dǎo)致當(dāng)前節(jié)點(diǎn)分裂每窖,此時(shí)MySQL不得不為了將新記錄插到合適位置而移動(dòng)數(shù)據(jù)帮掉,甚至目標(biāo)頁面可能已經(jīng)被回寫到磁盤上而從緩存中清掉,此時(shí)又要從磁盤上讀回來窒典,這增加了很多開銷蟆炊,同時(shí)頻繁的移動(dòng)、分頁操作造成了大量的碎片瀑志,得到了不夠緊湊的索引結(jié)構(gòu)涩搓,后續(xù)不得不通過OPTIMIZE TABLE來重建表并優(yōu)化填充頁面污秆。
反之,如果每次插入有序昧甘,那就會在當(dāng)前頁后面連續(xù)寫入良拼,寫不下就會重新分配一個(gè)節(jié)點(diǎn),內(nèi)存都是連續(xù)的充边,這樣效率自然也就最高了庸推。

問題二:如果二級索引儲存的也是數(shù)據(jù),那么每次插入mysql都不得不更新每棵索引樹浇冰,這樣就加劇了新增編輯時(shí)的性能損耗贬媒,并且這樣一來空間利用率也不高,產(chǎn)生了大量冗余數(shù)據(jù)湖饱。

聯(lián)合索引

聯(lián)合索引底層數(shù)據(jù)結(jié)構(gòu)長什么樣掖蛤?

聯(lián)合索引示意

比較相等時(shí),先比較第一列的值井厌,如果相等蚓庭,再繼續(xù)比較第二列,以此類推仅仆。

最左前綴原理

使用聯(lián)合索引時(shí)器赞,索引列的定義順序?qū)绊懙阶罱K查詢時(shí)索引的使用情況。例如聯(lián)合索引(a,b,c)墓拜,mysql會從最左邊的列優(yōu)先匹配港柜,如果最左邊的帶頭大哥沒有使用到,在未使用覆蓋索引的情況下咳榜,就只能全表掃描夏醉。
聯(lián)合底層數(shù)據(jù)結(jié)構(gòu)思考,mysql會優(yōu)先以聯(lián)合索引第一列匹配涌韩,此后才會匹配下一列畔柔,如果不指定第一列匹配的值,也就無法得知下一步查詢哪個(gè)節(jié)點(diǎn)臣樱。
另外還有一種情況靶擦,如果遇到 > < between等這樣的范圍查詢,那B+樹中也就無法對下一列進(jìn)行等值匹配了雇毫。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末玄捕,一起剝皮案震驚了整個(gè)濱河市枚粘,隨后出現(xiàn)的幾起案子席吴,更是在濱河造成了極大的恐慌捞蛋,老刑警劉巖拟杉,帶你破解...
    沈念sama閱讀 221,198評論 6 514
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件量承,死亡現(xiàn)場離奇詭異,居然都是意外死亡拿穴,警方通過查閱死者的電腦和手機(jī)默色,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,334評論 3 398
  • 文/潘曉璐 我一進(jìn)店門狮腿,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人吃度,你說我怎么就攤上這事贴硫。” “怎么了间护?”我有些...
    開封第一講書人閱讀 167,643評論 0 360
  • 文/不壞的土叔 我叫張陵兑牡,是天一觀的道長税灌。 經(jīng)常有香客問我菱涤,道長洛勉,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,495評論 1 296
  • 正文 為了忘掉前任攻走,我火速辦了婚禮,結(jié)果婚禮上玲销,老公的妹妹穿的比我還像新娘摘符。我一直安慰自己,他們只是感情好瘩绒,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,502評論 6 397
  • 文/花漫 我一把揭開白布锁荔。 她就那樣靜靜地躺著蝙砌,像睡著了一般。 火紅的嫁衣襯著肌膚如雪嘱丢。 梳的紋絲不亂的頭發(fā)上祠饺,一...
    開封第一講書人閱讀 52,156評論 1 308
  • 那天道偷,我揣著相機(jī)與錄音,去河邊找鬼勺鸦。 笑死,一個(gè)胖子當(dāng)著我的面吹牛懊渡,可吹牛的內(nèi)容都是我干的军拟。 我是一名探鬼主播,決...
    沈念sama閱讀 40,743評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼肾档,長吁一口氣:“原來是場噩夢啊……” “哼怒见!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起闺阱,我...
    開封第一講書人閱讀 39,659評論 0 276
  • 序言:老撾萬榮一對情侶失蹤馏颂,失蹤者是張志新(化名)和其女友劉穎棋傍,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體亿絮,經(jīng)...
    沈念sama閱讀 46,200評論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡麸拄,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,282評論 3 340
  • 正文 我和宋清朗相戀三年拢切,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片五慈。...
    茶點(diǎn)故事閱讀 40,424評論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡泻拦,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出争拐,到底是詐尸還是另有隱情晦雨,我是刑警寧澤,帶...
    沈念sama閱讀 36,107評論 5 349
  • 正文 年R本政府宣布音瓷,位于F島的核電站夹抗,受9級特大地震影響漠烧,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜已脓,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,789評論 3 333
  • 文/蒙蒙 一度液、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧堕担,春花似錦、人聲如沸佑惠。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,264評論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽赌厅。三九已至轿塔,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間洽议,已是汗流浹背漫拭。 一陣腳步聲響...
    開封第一講書人閱讀 33,390評論 1 271
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留审胚,地道東北人礼旅。 一個(gè)月前我還...
    沈念sama閱讀 48,798評論 3 376
  • 正文 我出身青樓,卻偏偏與公主長得像菲嘴,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子昭雌,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,435評論 2 359

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