MySQL 筆記 - 索引類(lèi)型

索引類(lèi)型包括 B-Tree霞玄、哈希索引没讲、R-Tree绩蜻、全文索引等,這里主要總結(jié) B-Tree 和哈希索引绿聘。

B-Tree 索引

以 B-Tree 為結(jié)構(gòu)的索引是最常見(jiàn)的索引類(lèi)型暗挑,比如 InnoDB 和 MyISAM 都是以 B-Tree 為索引結(jié)構(gòu)的索引,事實(shí)上是以 B+ Tree 為索引結(jié)構(gòu)斜友,B-Tree 和 B+Tree 區(qū)別在于炸裆,B+ Tree 在葉子節(jié)點(diǎn)上增加了順序訪問(wèn)指針,方便葉子節(jié)點(diǎn)的范圍遍歷鲜屏。這里主要介紹一下 InnoDB 和 MyISAM 兩種不同的索引烹看。

InnoDB

InnoDB 支持聚簇索引,聚簇索引和非聚簇索引嚴(yán)格來(lái)說(shuō)不是一種索引洛史,而是一種數(shù)據(jù)存儲(chǔ)方式惯殊,這個(gè)名字跟它本身的存儲(chǔ)方式有關(guān)系,“聚簇“表示數(shù)據(jù)行和相鄰的鍵值存儲(chǔ)在一起也殖,簡(jiǎn)單的說(shuō)土思,就是葉子節(jié)點(diǎn)中存儲(chǔ)的實(shí)際是真實(shí)的數(shù)據(jù)。InnoDB 通過(guò)主鍵聚集數(shù)據(jù)忆嗜,所以一個(gè)表只能有一個(gè)聚簇索引己儒,且必須有主鍵,如果沒(méi)有定義主鍵捆毫,且不存在非空索引可以代替闪湾,InnoDB 會(huì)隱式定義一個(gè)主鍵作為聚簇索引。

聚簇索引的二級(jí)索引存儲(chǔ)的不是指向行的物理位置的指針绩卤,而是行的主鍵值途样,所以如果通過(guò)二級(jí)索引查找行,需要找到二級(jí)索引的葉子結(jié)點(diǎn)獲得對(duì)應(yīng)的主鍵值濒憋,然后再去查找對(duì)應(yīng)的行何暇。對(duì)于 InnoDB,自適應(yīng)哈希索引可以減少這樣的重復(fù)工作凛驮。

MyISAM

MyISAM 支持非聚簇索引裆站,和 InnoDB 的區(qū)別在于,葉子結(jié)點(diǎn)上存的是指向?qū)?yīng)行的物理地址辐烂,也就是說(shuō)索引和數(shù)據(jù)實(shí)際是分開(kāi)存儲(chǔ)的遏插。

MyISAM 采用了前綴壓縮技術(shù),從而使得更多索引可以放入到內(nèi)存中纠修,默認(rèn)只壓縮字符串胳嘲,但是通過(guò)參數(shù)設(shè)置也可以對(duì)整數(shù)做壓縮。壓縮方法為扣草,完整保存索引塊中的第一個(gè)IE之了牛,然后將其他值和第一個(gè)值進(jìn)行比較得到相同前綴的字節(jié)數(shù)和剩余的不同后綴部分颜屠,把這部分存儲(chǔ)起來(lái)即可。例如鹰祸,索引塊中的第一個(gè)值是“perform”甫窟,第二個(gè)值是“performance”,那么第二個(gè)值的前綴壓縮后存儲(chǔ)的是類(lèi)似“7蛙婴,ance”這樣的形式粗井。MyISAM 對(duì)行指針也采用類(lèi)似的前綴壓縮方式。

壓縮可以使索引使用更少的空間街图,在某種程度上性能有所提升浇衬,但是代價(jià)是某些操作可能更慢。因?yàn)槊總€(gè)值的壓縮前綴都依賴(lài)前面的值餐济,所以 MyISAM 查找時(shí)無(wú)法在索引塊使用二分查找耘擂,只能從頭開(kāi)始掃描,正序掃描速度還不錯(cuò)絮姆,逆序掃描的話查找某一行的操作平均都需要掃描半個(gè)索引塊醉冤。對(duì)于 CPU 密集型應(yīng)用,掃描需要隨機(jī)查找篙悯,所以壓縮索引會(huì)使得索引查找慢很多蚁阳,而對(duì)于 I/O 密集型應(yīng)用,對(duì)于某些查詢(xún)的優(yōu)化更明顯辕近。

InnoDB 使用的是行鎖韵吨,所以支持事務(wù),而 MyISAM 使用的是表鎖移宅,不支持事務(wù)。

適用范圍

B-Tree 索引適用于區(qū)間查詢(xún)椿疗,因?yàn)?B-Tree 存儲(chǔ)后的葉子節(jié)點(diǎn)本身就是有序的漏峰,并且 B+ Tree 結(jié)構(gòu)還增加了葉子節(jié)點(diǎn)的連續(xù)順序指針,對(duì)于區(qū)間查詢(xún)來(lái)說(shuō)就更加方便了届榄。

哈希索引

哈希索引是基于哈希表實(shí)現(xiàn)的浅乔,只有精確匹配索引所有列的查詢(xún)才有效。方法是铝条,對(duì)所有的索引列計(jì)算一個(gè) hash code靖苇,hash code 作為索引,在哈希表中保存指向每個(gè)數(shù)據(jù)行的指針班缰。

優(yōu)點(diǎn)

  • 索引本身只存儲(chǔ) hash code贤壁,所以結(jié)構(gòu)很緊湊,并且查找速度很快

限制

  • 索引中的 hash code 是順序存儲(chǔ)的埠忘,但是 hash code 對(duì)應(yīng)的數(shù)據(jù)并不是順序的脾拆,所以無(wú)法用于排序
  • 不支持部分索引列匹配查找馒索,因?yàn)楣K饕鞘褂盟饕械娜績(jī)?nèi)容來(lái)計(jì)算 hash code
  • 只支持等值比較,不支持范圍查詢(xún)
  • 如果哈希沖突嚴(yán)重時(shí)名船,必須遍歷鏈表中所有行指針
  • 哈希沖突嚴(yán)重的話绰上,索引維護(hù)操作的代價(jià)也很高

InnoDB 的自適應(yīng)哈希索引

首先,請(qǐng)注意渠驼,自適應(yīng)哈希索引對(duì)于用戶(hù)來(lái)說(shuō)是無(wú)感知的蜈块,這是一個(gè)完全自動(dòng)、內(nèi)部的行為迷扇,用戶(hù)無(wú)法控制或者配置疯趟,但是可以關(guān)閉。

當(dāng) InnoDB 注意到某個(gè)索引值被使用的非常頻繁時(shí)谋梭,它會(huì)在內(nèi)存中基于 B-Tree 索引之上再創(chuàng)建一個(gè)哈希索引信峻,這樣 B-Tree 也可以具有哈希索引的一些優(yōu)點(diǎn),比如快速的哈希查找瓮床。

當(dāng)然如果存儲(chǔ)引擎不支持哈希索引盹舞,用戶(hù)也可以自定義哈希索引,這樣性能會(huì)比較高隘庄,缺陷是需要自己維護(hù)哈希值踢步,如果采用這種方法,不要使用 SHA1()MD5() 作為哈希函數(shù)丑掺,因?yàn)檫@兩個(gè)是強(qiáng)加密函數(shù)获印,設(shè)計(jì)目標(biāo)是最大限度消除沖突,生成的 hash code 是一個(gè)非常長(zhǎng)的字符串街州,浪費(fèi)大量的空間兼丰,哈希索引中對(duì)于索引的沖突要求沒(méi)有那么高。

索引的優(yōu)點(diǎn)

  • 使用索引可以減少服務(wù)器需要掃描的數(shù)據(jù)量
  • 使用索引可以幫助服務(wù)器避免排序和臨時(shí)表
  • 使用索引可以將隨機(jī) I/O 變?yōu)轫樞?I/O

但是不是所有情況下唆缴,索引都是最好的解決方案鳍征,對(duì)于非常小的表來(lái)說(shuō),大部分情況下簡(jiǎn)單的全表掃描更高效面徽,對(duì)于中到大型表艳丛,索引就比較有效,對(duì)于特大型的表來(lái)說(shuō)趟紊,分區(qū)會(huì)更加有效氮双。

Reference

《高性能 MySQL》

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市霎匈,隨后出現(xiàn)的幾起案子戴差,更是在濱河造成了極大的恐慌,老刑警劉巖唧躲,帶你破解...
    沈念sama閱讀 217,907評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件造挽,死亡現(xiàn)場(chǎng)離奇詭異碱璃,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)饭入,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,987評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén)嵌器,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人谐丢,你說(shuō)我怎么就攤上這事爽航。” “怎么了乾忱?”我有些...
    開(kāi)封第一講書(shū)人閱讀 164,298評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵讥珍,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我窄瘟,道長(zhǎng)衷佃,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,586評(píng)論 1 293
  • 正文 為了忘掉前任蹄葱,我火速辦了婚禮氏义,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘图云。我一直安慰自己惯悠,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,633評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布竣况。 她就那樣靜靜地躺著烟号,像睡著了一般蹲姐。 火紅的嫁衣襯著肌膚如雪擒滑。 梳的紋絲不亂的頭發(fā)上帆精,一...
    開(kāi)封第一講書(shū)人閱讀 51,488評(píng)論 1 302
  • 那天,我揣著相機(jī)與錄音嘀掸,去河邊找鬼紫岩。 笑死,一個(gè)胖子當(dāng)著我的面吹牛睬塌,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播歇万,決...
    沈念sama閱讀 40,275評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼揩晴,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了贪磺?” 一聲冷哼從身側(cè)響起硫兰,我...
    開(kāi)封第一講書(shū)人閱讀 39,176評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎寒锚,沒(méi)想到半個(gè)月后劫映,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體违孝,經(jīng)...
    沈念sama閱讀 45,619評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,819評(píng)論 3 336
  • 正文 我和宋清朗相戀三年泳赋,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了雌桑。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,932評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡祖今,死狀恐怖校坑,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情千诬,我是刑警寧澤耍目,帶...
    沈念sama閱讀 35,655評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站徐绑,受9級(jí)特大地震影響邪驮,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜傲茄,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,265評(píng)論 3 329
  • 文/蒙蒙 一毅访、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧烫幕,春花似錦俺抽、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,871評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至捷犹,卻和暖如春弛饭,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背萍歉。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,994評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工侣颂, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人枪孩。 一個(gè)月前我還...
    沈念sama閱讀 48,095評(píng)論 3 370
  • 正文 我出身青樓憔晒,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親蔑舞。 傳聞我的和親對(duì)象是個(gè)殘疾皇子拒担,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,884評(píng)論 2 354

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