對于Mysql索引的理解

前言:

? ? 對于數(shù)據(jù)庫中的索引,一個非常好的類比是把數(shù)據(jù)庫索引看作是書的索引棠众。如果你有一本關(guān)于狗的書,你想要找關(guān)于‘黃金獵犬’的那部分。當(dāng)你可以通過在書背的索引找到哪幾頁有關(guān)于‘黃金獵犬’信息的時候越平,你為什么要翻完正本書 - 這相當(dāng)于數(shù)據(jù)庫中的全表掃描。同樣的灵迫,就像一本書的索引包含頁碼一樣秦叛,數(shù)據(jù)庫的索引包含了指針,指向你在SQL中想要查詢的值所在的行瀑粥。

? ? 對于數(shù)據(jù)庫也是一樣挣跋,但是數(shù)據(jù)庫更加復(fù)雜,因?yàn)槠洳樵儾粌H會有等值查詢(=)狞换,還有范圍查詢(>, < , between, in)浆劲,like模糊查詢,以及交集查詢(AND)哀澈,并集查詢(OR)等等牌借。

數(shù)據(jù)庫索引:

? ? 基于以上的分析,那么數(shù)據(jù)庫應(yīng)該采用何種方式來應(yīng)對所有的問題呢割按?

? ? 分段處理膨报,可否將數(shù)據(jù)分段呢?假如有1000條數(shù)據(jù)适荣,1-100分成第一段现柠,101-200分成第二段...這樣,如果我需要查詢108條數(shù)據(jù)弛矛,則只需要去找第二段數(shù)據(jù)就好了够吩,是不是節(jié)省了大量的查詢時間呢?

? ? 我們知道,在數(shù)據(jù)結(jié)構(gòu)中丈氓,有二叉數(shù)的結(jié)構(gòu)周循,查詢的時間復(fù)雜度為O(logN),具有不錯的查詢性能万俗,可我們知道如果采用這種數(shù)據(jù)接口作為索引的數(shù)據(jù)結(jié)構(gòu)湾笛,那么索引數(shù)據(jù)就必須按照這種結(jié)構(gòu)存儲,而數(shù)據(jù)庫的數(shù)據(jù)是保存在磁盤上的闰歪,我們不可能一次性將數(shù)據(jù)全部加載到內(nèi)存中嚎研,只能是采用預(yù)讀的方式,每次加載一部分?jǐn)?shù)據(jù)到內(nèi)存中库倘。

I/O 和預(yù)讀:

? ? Mysql數(shù)據(jù)庫數(shù)據(jù)訪問是基于磁盤的訪問形式临扮,而磁盤訪問论矾,每一次的磁盤IO的時間約為9ms,看似時間很短杆勇,但是我們要知道的是計(jì)算機(jī)執(zhí)行指令的速度是遠(yuǎn)遠(yuǎn)快于磁盤IO的拇囊。

局部預(yù)讀性原理:

? ? 由于磁盤IO的高耗時操作,計(jì)算機(jī)系統(tǒng)做了很多優(yōu)化靶橱,當(dāng)一次磁盤IO時寥袭,不僅會讀取當(dāng)前磁盤地址的數(shù)據(jù),還會把相鄰的數(shù)據(jù)也一起讀到內(nèi)存中关霸,因?yàn)橐话闱闆r下传黄,其相鄰的數(shù)據(jù)很快也會被訪問到,這就是局部預(yù)讀性原理队寇。因此

? ? 每一次磁盤IO讀取的數(shù)據(jù)我們稱為一頁數(shù)據(jù)膘掰,不同的操作系統(tǒng)下,一頁數(shù)據(jù)的大小不一定佳遣,一般為4K或者8K识埋,即一頁數(shù)據(jù)讀取就是發(fā)生了一次IO操作。

索引數(shù)據(jù)接口:

1

B+樹分析:

????所有真實(shí)數(shù)據(jù)存在與葉子節(jié)點(diǎn)

? ? 淡藍(lán)色方框表示一個磁盤塊零渐,每個磁盤塊中包含幾個數(shù)據(jù)項(xiàng)(深藍(lán)色)窒舟,和指針(黃色)

? ? 非葉子節(jié)點(diǎn)不存儲真實(shí)數(shù)據(jù),只存儲指引搜索方向的數(shù)據(jù)項(xiàng)诵盼,如17惠豺,35等數(shù)據(jù)并不是真實(shí)存在與數(shù)據(jù)表中的數(shù)據(jù)。

B+樹的查找過程:

? ? 如果我需要查詢數(shù)據(jù)項(xiàng)29风宁,那么首先會發(fā)生一次磁盤IO將磁盤塊1加載到內(nèi)存中洁墙, 此時發(fā)生了一次磁盤IO,然后在內(nèi)存中再利用二分查找去確定出29在17和35之間戒财,即定位到磁盤塊1中的黃色的P2指針(實(shí)際上索引根節(jié)點(diǎn)會常駐內(nèi)存中热监,故這一次的IO是不需要的)

? ? 再利用P2指針指向的磁盤塊3,將磁盤塊3加載到內(nèi)存中饮寞, 此時發(fā)生了第二次磁盤IO孝扛,再利用二分查找法確定29位于26和30之間,從而定位到磁盤塊3中的P2指針

????再利用P2指針去加載磁盤塊8到內(nèi)存中骂际,此時發(fā)生了第三次磁盤IO疗琉,同時,經(jīng)過內(nèi)存中的二分查找法定位到了真正需要尋找的數(shù)據(jù)項(xiàng)29歉铝,整個查找過程結(jié)束。

? ? 整個過程中凑耻,一共經(jīng)歷了三次磁盤IO太示,而在真實(shí)的使用場景中柠贤,三層的B+樹可以表示百萬行的數(shù)據(jù),試想一下类缤,對于一個包含百萬行數(shù)據(jù)的表數(shù)據(jù)查詢臼勉,只需要三次磁盤IO,那么性能提升將是巨大的餐弱。

B+樹的性質(zhì):

? ? 通過上面的例子宴霸,分析一下B+樹的基本性質(zhì)。

? ? 磁盤IO的次數(shù)取決于B+樹的高度H膏蚓,假設(shè)當(dāng)前數(shù)據(jù)表的數(shù)據(jù)為N個瓢谢,每個磁盤塊的數(shù)據(jù)項(xiàng)的數(shù)量是M個,則樹高 H = log(M + 1)N驮瞧, 當(dāng)數(shù)據(jù)量N一定的情況下氓扛,M越大,H越小论笔,這樣查詢數(shù)據(jù)所需要磁盤IO次數(shù)就越小采郎,查詢性能就會越好,所以如何增加磁盤塊中的數(shù)據(jù)項(xiàng)是關(guān)鍵狂魔。

? ? M = 磁盤塊的大小/數(shù)據(jù)項(xiàng)的大小蒜埋, 而磁盤塊的大小我們知道是固定的,那如果每個數(shù)據(jù)項(xiàng)占的空間越小最楷,是不是數(shù)據(jù)項(xiàng)的數(shù)量就越多呢理茎?這也是為什么要求索引字段盡量小的原因,還有就是為什么Mysql中B+樹要求把真實(shí)數(shù)據(jù)放在葉子節(jié)點(diǎn)而不是內(nèi)存節(jié)點(diǎn)管嬉,就是為了增加每個磁盤塊中的數(shù)據(jù)項(xiàng)的數(shù)量皂林,為了降低整個B+樹的高度,為了減少磁盤IO的次數(shù)蚯撩。

Mysql索引分類:

? ? 普通索引:最基本的索引即NORMAL

? ? 唯一索引:與普通索引類型不同的是唯一索引的列值必須唯一础倍,允許空值。

? ? 全文索引:FullText 胎挎,僅適用于MyISAM引擎的數(shù)據(jù)表沟启,只能作用于CHAR,VARCHAR犹菇,TEXT數(shù)據(jù)類型的列

? ? 組合索引:將幾個列作為一條索引進(jìn)行檢索德迹,需要滿足最左前綴匹配原則,直到遇到范圍查詢則停止匹配揭芍。對于等于胳搞,IN可以亂序,Mysql的查詢優(yōu)化器會幫你優(yōu)化成滿足索引被識別的形式。

Hash索引和B+樹索引的區(qū)別:

? ? 我們直到Hash索引的等值查詢效率極高肌毅,可以理解為Map筷转,但是存在的缺點(diǎn)是不夠靈活,不能支持范圍查詢悬而,比如查詢10-100之間呜舒,因?yàn)镠ashMap作為索引結(jié)構(gòu)的話,是無序的笨奠。另外當(dāng)數(shù)據(jù)量大的時候袭蝗,勢必會存在Hash沖突。

? ? 而B+樹雖然在查詢效率上沒有Hash的效率高般婆,但是B+樹上的數(shù)據(jù)是有序的到腥,其對于查找、刪除腺兴、插入操作都可以可以在對數(shù)時間內(nèi)完成

????故B+樹作為常用的索引數(shù)據(jù)結(jié)構(gòu)左电。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市页响,隨后出現(xiàn)的幾起案子篓足,更是在濱河造成了極大的恐慌,老刑警劉巖闰蚕,帶你破解...
    沈念sama閱讀 217,734評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件栈拖,死亡現(xiàn)場離奇詭異,居然都是意外死亡没陡,警方通過查閱死者的電腦和手機(jī)涩哟,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,931評論 3 394
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來盼玄,“玉大人贴彼,你說我怎么就攤上這事“6” “怎么了器仗?”我有些...
    開封第一講書人閱讀 164,133評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長童番。 經(jīng)常有香客問我精钮,道長,這世上最難降的妖魔是什么剃斧? 我笑而不...
    開封第一講書人閱讀 58,532評論 1 293
  • 正文 為了忘掉前任轨香,我火速辦了婚禮,結(jié)果婚禮上幼东,老公的妹妹穿的比我還像新娘臂容。我一直安慰自己科雳,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,585評論 6 392
  • 文/花漫 我一把揭開白布策橘。 她就那樣靜靜地躺著炸渡,像睡著了一般娜亿。 火紅的嫁衣襯著肌膚如雪丽已。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,462評論 1 302
  • 那天买决,我揣著相機(jī)與錄音沛婴,去河邊找鬼。 笑死督赤,一個胖子當(dāng)著我的面吹牛嘁灯,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播躲舌,決...
    沈念sama閱讀 40,262評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼丑婿,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了没卸?” 一聲冷哼從身側(cè)響起羹奉,我...
    開封第一講書人閱讀 39,153評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎约计,沒想到半個月后诀拭,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,587評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡煤蚌,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,792評論 3 336
  • 正文 我和宋清朗相戀三年耕挨,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片尉桩。...
    茶點(diǎn)故事閱讀 39,919評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡筒占,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出蜘犁,到底是詐尸還是另有隱情翰苫,我是刑警寧澤,帶...
    沈念sama閱讀 35,635評論 5 345
  • 正文 年R本政府宣布沽瘦,位于F島的核電站革骨,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏析恋。R本人自食惡果不足惜良哲,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,237評論 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望助隧。 院中可真熱鬧筑凫,春花似錦滑沧、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,855評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至棚潦,卻和暖如春令漂,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背丸边。 一陣腳步聲響...
    開封第一講書人閱讀 32,983評論 1 269
  • 我被黑心中介騙來泰國打工叠必, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人妹窖。 一個月前我還...
    沈念sama閱讀 48,048評論 3 370
  • 正文 我出身青樓纬朝,卻偏偏與公主長得像,于是被迫代替她去往敵國和親骄呼。 傳聞我的和親對象是個殘疾皇子共苛,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,864評論 2 354

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