Mysql索引原理

參考出處

陳Chuan大佬系列隧膘,簡書過500贊的博客
http://www.reibang.com/p/d7665192aaaf

一文看懂 聚簇索引脖律、非聚簇索引 和InnoDB和Myisam的區(qū)別
https://blog.csdn.net/lisuyibmd/article/details/53004848

Mysql B+樹的插入刪除示损,看這一篇就夠了崭倘,有圖有真想
https://blog.csdn.net/sunshine_lyn/article/details/82747596

概論

image

image

幾個概念:

  • InnoDB的行鎖是建立在索引的基礎(chǔ)之上的聊替,行鎖鎖的是索引,不是數(shù)據(jù)开财,所以提高并發(fā)寫的能力要在查詢字段添加索引

  • 主索引和輔助索引:主索引就是主鍵索引汉柒,輔助索引就是根據(jù)業(yè)務(wù)需要,自己設(shè)置的普通的非主鍵的索引床未。這個在Myisam里面區(qū)別不大竭翠,但是在Innodb的時候差別很大

  • 聚簇索引:Innodb的主索引采用的是聚簇索引振坚,一個表只能有1個聚簇索引薇搁,因為表數(shù)據(jù)存儲的物理位置是唯一的。聚簇索引的value存的就是真實的數(shù)據(jù)渡八,不是數(shù)據(jù)的地址啃洋。主索引樹里面包含了真實的數(shù)據(jù)。key是主鍵值屎鳍,value值就是data宏娄,key值按照B+樹的規(guī)則分散排布的葉子節(jié)點。

  • 非聚簇索引:Myisam的主索引和輔助索引都采用的是非聚簇索引逮壁,索引和表數(shù)據(jù)是分離的孵坚,索引的value值指向的物理的存儲地址。

  • Innodb的索引:主索引采用聚簇索引,葉子節(jié)點的value值卖宠,直接存儲的真實的數(shù)據(jù)巍杈。輔助索引是非聚簇索引,value值指向主索引的位置扛伍。所以Innodb中筷畦,根據(jù)輔助索引查詢值需要遍歷2次B+樹,同時主鍵的長度越短越好刺洒,越短副主索引的value值就越小鳖宾。但是Innodb中根據(jù)主鍵進行范圍查詢,會特別快逆航。

  • Myisam的索引:主索引和輔助索引都是非聚簇索引

  • B+樹:不管是什么索引鼎文,在mysql中的數(shù)據(jù)結(jié)構(gòu)都是B+樹的結(jié)構(gòu),可以充分利用數(shù)據(jù)塊因俐,來減少IO查詢的次數(shù)漂问,提升查詢的效率,如圖所示女揭,一個數(shù)據(jù)塊data里面蚤假,存儲了很多個相鄰key的value值,所有的非葉子節(jié)點都不存儲數(shù)據(jù)吧兔,都是指針磷仰。

  • Mysql采用B+樹的優(yōu)點:IO讀取次數(shù)少(每次都是頁讀取)境蔼,范圍查找更快捷(相鄰頁之間有指針)

聚集索引

  1. 聚集索引就是葉子節(jié)點的順序和物理存儲的順序是一樣的灶平,所以范圍查找的時候效率很高,但是DML操作的時候箍土,為了維護物理存儲的順序和葉子節(jié)點一樣逢享,涉及到大量的數(shù)據(jù)位移調(diào)整。

  2. 聚簇索引的順序就是數(shù)據(jù)的物理存儲順序吴藻,所以一個表最多只能有一個聚簇索引瞒爬,因為物理存儲只能有一個順序。正因為一個表最多只能有一個聚簇索引沟堡,所以它顯得更為珍貴侧但,一個表設(shè)置什么為聚簇索引對性能很關(guān)鍵

舉例:主鍵為id的表中,范圍查找 where id<1000 and id>200
則只需要找到ID=200和 ID=1000的葉子節(jié)點對應(yīng)的位置航罗,撈取數(shù)據(jù)塊中間的所有的數(shù)據(jù)禀横,就是要查找的范圍數(shù)據(jù)了。但是如果以前沒有ID=300這個數(shù)據(jù)粥血,現(xiàn)在新增一個ID=300的數(shù)據(jù)柏锄,那么 ID>300的所有的數(shù)據(jù)都要往后挪一個位置酿箭。

樹形結(jié)構(gòu)科普

https://blog.csdn.net/zwz2011303359/article/details/63262541

  1. 傳說中的葉子節(jié)點,指的是最外層的節(jié)點趾娃,就像一棵樹七问,只有最外層的節(jié)點才長葉子

  2. 二叉搜索樹的特點:

  • 所有結(jié)點至多擁有兩個兒子(Left和Right);
  • 所有結(jié)點只存儲一個關(guān)鍵字(可以理解為索引茫舶,比如ID值)械巡;
  • 非葉子結(jié)點的左指針指向小于其關(guān)鍵字的子樹,右指針指向大于其關(guān)鍵字的子樹饶氏;
  • 二叉搜索樹如果是滿二叉樹時讥耗,查找的性能逼近有序數(shù)組的二分查找,同時插入的性能遠遠高于有序數(shù)組疹启,因為只需要再對應(yīng)的節(jié)點添加引用古程,而不需要移動任何老的節(jié)點
  1. B-Tree的特點
  • 所有鍵值分布在整個樹中(區(qū)別與B+樹,B+樹的值只分部在葉子節(jié)點上)
  • 任何關(guān)鍵字出現(xiàn)且只出現(xiàn)在一個節(jié)點中(區(qū)別與B+樹)
  • 搜索有可能在非葉子節(jié)點結(jié)束(區(qū)別與B+樹喊崖,因為值都在葉子節(jié)點上挣磨,只有搜到葉子節(jié)點才能拿到值)
  • 在關(guān)鍵字全集內(nèi)做一次查找,性能逼近二分查找算法

B+樹的結(jié)構(gòu)特點

  1. B+樹索引并不能找到一個給定鍵值的具體行荤懂,它找到的只是被查找數(shù)據(jù)行所在的頁茁裙,接著數(shù)據(jù)庫會把頁讀入到內(nèi)存,再在內(nèi)存中進行查找节仿,最后得到要查找的數(shù)據(jù)晤锥。數(shù)據(jù)的讀取是精確到頁的,因為頁是計算機管理存儲器的邏輯塊廊宪,IO的磁盤讀取矾瘾,每次都讀取數(shù)據(jù)的大小是一個頁大小的整數(shù)倍。
  2. 假設(shè)B+Tree的高度為h箭启,一次檢索最多需要h-1次I/O(根節(jié)點常駐內(nèi)存)壕翩,復(fù)雜度O(h) = O(logmN),m指的是一個節(jié)點存儲的數(shù)據(jù)的個數(shù)傅寡。實際應(yīng)用場景中放妈,M通常較大,常常超過100赏僧,因此樹的高度一般都比較小大猛,通常不超過3。
  1. B+樹與B樹的不同在于:
  • 所有關(guān)鍵字存儲在葉子節(jié)點淀零,非葉子節(jié)點不存儲真正的data
  • 為所有葉子節(jié)點(左右相鄰的節(jié)點之間)增加了一個鏈指針
  1. 為什么數(shù)據(jù)庫使用B+而不使用紅黑樹呢?
  • 計算器在IO磁盤讀取的時候膛壹,為了降低讀取的次數(shù)驾中,默認一次會讀取一個頁的數(shù)據(jù)量唉堪,MySQL(默認使用InnoDB引擎),將記錄按照頁的方式進行管理,每頁大小默認為16K(這個值可以修改)。linux 默認頁大小為4K肩民。所以每次IO讀取唠亚,都是讀取一個頁的數(shù)據(jù)量,所以B樹的節(jié)點都是存儲一個頁的節(jié)點持痰,這樣的查詢效率才是最高的
  • 每次新建節(jié)點時灶搜,直接申請一個頁的空間,這樣就保證一個節(jié)點物理上也存儲在一個頁里工窍,加之計算機存儲分配都是按頁對齊的割卖,就實現(xiàn)了一個結(jié)點只需一次I/O。這樣大大降低了樹的高度
  1. 為什么mysql的索引使用B+樹而不是B樹呢患雏?
  • 范圍查找更快鹏溯,mysql是關(guān)系型數(shù)據(jù)庫,經(jīng)常會按照區(qū)間來訪問某個索引列淹仑,B+樹的葉子節(jié)點間按順序建立了鏈指針丙挽,加強了區(qū)間訪問性,所以B+樹對索引列上的區(qū)間范圍查詢很友好匀借。而B樹的數(shù)據(jù)有一部分存在在非葉子節(jié)點上面颜阐,而且默認的B樹的相鄰的葉子節(jié)點之間是沒有指針的,所以范圍查找相對更慢吓肋。
  • 降低樹的高度瞬浓,但是最底下一層的節(jié)點會更多,因為所有的數(shù)據(jù)都堆積在最底下一層了蓬坡,用空間換速度猿棉。B+樹更適合外部存儲(一般指磁盤存儲),由于內(nèi)節(jié)點(非葉子節(jié)點)不存儲data,所以一個節(jié)點可以存儲更多的內(nèi)節(jié)點屑咳,每個節(jié)點能索引的范圍更大更精確萨赁。也就是說使用B+樹單次磁盤IO的信息量相比較B樹更大,IO效率更高

B+樹插入和刪除的邏輯

https://blog.csdn.net/sunshine_lyn/article/details/82747596

  1. 插入:和紅黑樹特別像兆龙,新數(shù)據(jù)插入到一個滿了的節(jié)點中時杖爽,會優(yōu)先進行左旋右旋,如果鄰近的節(jié)點都滿了的話,會取中間的一個key往上一個層級插入紫皇,直至到Root節(jié)點,樹的高度的增加慰安,都是通過根節(jié)點的拆分來完成的,這保證了所有左右節(jié)點的高度差不超過1
  2. 刪除:會進行調(diào)整優(yōu)化樹形結(jié)構(gòu)聪铺,使樹的數(shù)據(jù)更分散化焕,以及降低樹的高度。比如如果該節(jié)點的數(shù)據(jù)過少铃剔,可以從鄰近的節(jié)點左旋 右旋數(shù)據(jù)來填充撒桨〔榭蹋可能的話,降低一個樹的高度凤类。

為什么Mysql不選擇Hash索引穗泵?

Hash索引的優(yōu)勢是精確查找的話,速度會更快谜疤,為什么不選擇Hash索引

  1. Hash索引不適合范圍查找佃延,而B+樹特別適合范圍查找(特別是聚簇索引的時候)
  2. Hash索引每次查詢要加載所有的索引數(shù)據(jù)到內(nèi)存當(dāng)中,而B+樹只需要根據(jù)匹配規(guī)則選擇對應(yīng)的葉子數(shù)據(jù)加載即可
  3. 另外B+樹引入了緩存機制 和 數(shù)據(jù)頁技術(shù)來提升性能(不過理論上來說夷磕,這兩個特性Hash索引也可以實現(xiàn))

如果你覺得對你有幫助的話履肃,就給我點贊吧!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末企锌,一起剝皮案震驚了整個濱河市榆浓,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌撕攒,老刑警劉巖陡鹃,帶你破解...
    沈念sama閱讀 206,723評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異抖坪,居然都是意外死亡萍鲸,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,485評論 2 382
  • 文/潘曉璐 我一進店門擦俐,熙熙樓的掌柜王于貴愁眉苦臉地迎上來脊阴,“玉大人,你說我怎么就攤上這事蚯瞧『倨冢” “怎么了?”我有些...
    開封第一講書人閱讀 152,998評論 0 344
  • 文/不壞的土叔 我叫張陵埋合,是天一觀的道長备徐。 經(jīng)常有香客問我,道長甚颂,這世上最難降的妖魔是什么蜜猾? 我笑而不...
    開封第一講書人閱讀 55,323評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮振诬,結(jié)果婚禮上蹭睡,老公的妹妹穿的比我還像新娘。我一直安慰自己赶么,他們只是感情好肩豁,可當(dāng)我...
    茶點故事閱讀 64,355評論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般蓖救。 火紅的嫁衣襯著肌膚如雪班眯。 梳的紋絲不亂的頭發(fā)上殴穴,一...
    開封第一講書人閱讀 49,079評論 1 285
  • 那天厘贼,我揣著相機與錄音污呼,去河邊找鬼切揭。 笑死聊记,一個胖子當(dāng)著我的面吹牛楼熄,可吹牛的內(nèi)容都是我干的拗盒。 我是一名探鬼主播础钠,決...
    沈念sama閱讀 38,389評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼恰力,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了旗吁?” 一聲冷哼從身側(cè)響起踩萎,我...
    開封第一講書人閱讀 37,019評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎很钓,沒想到半個月后香府,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,519評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡码倦,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,971評論 2 325
  • 正文 我和宋清朗相戀三年企孩,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片袁稽。...
    茶點故事閱讀 38,100評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡勿璃,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出推汽,到底是詐尸還是另有隱情补疑,我是刑警寧澤,帶...
    沈念sama閱讀 33,738評論 4 324
  • 正文 年R本政府宣布歹撒,位于F島的核電站莲组,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏栈妆。R本人自食惡果不足惜胁编,卻給世界環(huán)境...
    茶點故事閱讀 39,293評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望鳞尔。 院中可真熱鬧嬉橙,春花似錦、人聲如沸寥假。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,289評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽糕韧。三九已至枫振,卻和暖如春喻圃,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背粪滤。 一陣腳步聲響...
    開封第一講書人閱讀 31,517評論 1 262
  • 我被黑心中介騙來泰國打工斧拍, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人杖小。 一個月前我還...
    沈念sama閱讀 45,547評論 2 354
  • 正文 我出身青樓肆汹,卻偏偏與公主長得像,于是被迫代替她去往敵國和親予权。 傳聞我的和親對象是個殘疾皇子昂勉,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,834評論 2 345