索引那些事

最近在重構(gòu)自己工作上寫的代碼,重構(gòu)完后也開始考慮要做一些數(shù)據(jù)庫優(yōu)化规揪。其中一項工作就是重新審視之前設(shè)置的索引是否合理桥氏。于是這周都在反復看《極客時間》上面的Mysql實戰(zhàn)的專欄,先惡補下索引方面的基礎(chǔ)知識猛铅,本文在此做一些記錄识颊。

0、背景

本文以Mysql中的InnoDB的使用為例

1奕坟、索引解決的問題

索引,可以理解為一本書的目錄清笨,它要解決的是提高查詢效率的問題月杉。當我們要查找一本書的某個內(nèi)容時,如果沒有目錄抠艾,就得一頁一頁去找苛萎,效率非常低。但當我們有一個目錄時,直接根據(jù)要查找的關(guān)鍵詞腌歉,就可以在目錄上搜尋主題蛙酪,從而更快地搜尋到關(guān)心的內(nèi)容

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

既然是為了方便查找數(shù)據(jù)翘盖,那么我們就會根據(jù)數(shù)據(jù)的特性桂塞,找到出能提高其讀寫效率的數(shù)據(jù)模型,這里我們簡單說三種:

  • 有序數(shù)組
    該模型的特點是 靜態(tài)馍驯、順序 存儲阁危,不適合需要經(jīng)常插入的場景
  • 哈希表
    適合等值查詢的場景,經(jīng)常見的就是key-value汰瘫;由于插入的數(shù)據(jù)都是無序的狂打,哈希表在進行范圍查詢或有序查詢時,就不太適用混弥;
  • 二叉樹
    出現(xiàn)的原因主要是讓查詢盡可能少的訪問磁盤趴乡;其特點是leftChild < parent< rightChild,所以樹也是一個有序的結(jié)構(gòu)蝗拿;

3晾捏、索引的類型

索引類型分兩種,根據(jù)其索引樹葉子節(jié)點的內(nèi)容蛹磺,區(qū)分成兩類粟瞬,一個是普通索引,一個是主鍵索引萤捆;普通索引又稱為二級索引裙品,為啥稱為二級索引呢?大家可以看下圖

dcda101051f28502bd5c4402b292e38d.png
圖片來自極客時間俗或,侵刪

例如我對表A建立了一個普通索引k市怎,Mysql中便會建立兩顆索引樹,一個是主鍵索引樹辛慰,一個是普通索引樹区匠,如上圖。
那么大家可能會問帅腌,基于主鍵索引普通索引的查詢有什么區(qū)別驰弄?
我們用兩條Mysql語句進行說明。
如果是基于主鍵索引速客,select * from T where id = 500, 它只用搜索主鍵索引樹戚篙;
如果是基于普通索引,select * from T where k = 3溺职,它的搜索過程如下:

  1. 先到K索引樹上找到k = 3的值
  2. 找到后岔擂,取出葉子節(jié)點的值位喂,得知主鍵為300,則再去主索引樹搜尋ID = 300的節(jié)點乱灵,再取出數(shù)據(jù)塑崖;

從此可以得出,普通索引要比主鍵索引的查詢多查一次索引樹痛倚,這個過程我們稱為 回表规婆,我們一般都建議,用主鍵查詢状原,就是為了減少回表的過程聋呢;

4、建表時最好用自增Id主鍵颠区,為什么削锰?

這個問題,主要是從性能和存儲的方面來說的毕莱。首先我們先看下索引的維護過程

4.1 索引維護過程

我們知道器贩,當插入新數(shù)據(jù)時,索引也是要相應維護朋截,如果我們新插一條數(shù)據(jù)蛹稍,而且是用自增ID的話,基本上數(shù)據(jù)是在最新ID的后面部服,整顆樹還是保持有序的唆姐,不需要變動,但如果現(xiàn)插入一條數(shù)據(jù)廓八,例如在id = 500前插入一個id = 400的值奉芦,這會就需要調(diào)整樹結(jié)構(gòu),把值插進去剧蹂。声功。就很有可能會出現(xiàn)數(shù)據(jù)頁滿了的情況,導致進行分頁宠叼,這樣Mysql就會把一部分數(shù)據(jù)挪過去先巴,導致性能受到影響。同樣的冒冬,如果我們刪除了一些數(shù)據(jù)伸蚯,數(shù)據(jù)庫也會做合并。

4.2 場景

比如現(xiàn)在有一個用戶表简烤,用戶表中有一個唯一標志剂邮,身份證。
我們假設(shè)用身份證做主鍵乐埠,會出現(xiàn)兩個問題:

  • 一個主鍵就會占用至少二十個字節(jié)抗斤,后邊新建普通索引的時候,該普通索引上的每一個葉子節(jié)點丈咐,至少有二十個字節(jié)瑞眼,整體算下來會占較大空間。
  • 用身份證做主鍵并不能保證有序插入棵逊,插入時可能產(chǎn)生數(shù)據(jù)的挪動伤疙,從而降低查詢性能

當然也有些場景是適合用業(yè)務字段作為主鍵的,什么情況呢辆影?
當該字段是表中的唯一索引 徒像,典型場景就是 KV場景

既然表中沒有其他索引,也不用考慮葉子節(jié)點的大小了蛙讥,直接將其設(shè)成主鍵锯蛀,這樣也不用回表查詢

5、索引的其他概念

在使用索引的時候次慢,我們還經(jīng)常聽到這樣一些概念,例如 覆蓋索引旁涤,前綴索引,索引下推迫像,下面我們再分別介紹一些這些概念是什么

5.1 覆蓋索引

覆蓋索引的定義就是 定義的索引已經(jīng)覆蓋了查詢需求劈愚,該索引查詢出的結(jié)果已經(jīng)滿足需求

還是第三節(jié)的這個圖,k是普通索引闻妓,ID是主鍵菌羽,我們看看下列sql語句

 select ID from T where k between a and b

這里,通過這句sql得出的查詢結(jié)果已經(jīng)能滿足查詢到ID的需求了由缆,不需要再回表(回到主索引樹)查詢一次注祖,索引k 就 被稱為 覆蓋索引

由上得知,覆蓋索引主要是為了減少索引樹的搜索次數(shù)犁功;如果有些字段查詢非常高頻氓轰,可以考慮建立一些索引,覆蓋其查詢需求浸卦;

5.2 前綴索引

前綴索引在百度上的定義多為 用聯(lián)合索引的最左N個字段或者字符串的最左M個字符進行查詢的索引署鸡。在這里大家可能會一直冒問號了,為什么是最左限嫌?為什么最左N個字段就可以加速查詢靴庆?
首先,要知道聯(lián)合索引的存儲結(jié)構(gòu)怒医,索引項按照索引定義中出現(xiàn)的字段項進行排序炉抒,比如我現(xiàn)在給用戶表里面建立了(name,age)的聯(lián)合索引稚叹,建立后的數(shù)據(jù)存儲結(jié)構(gòu)可看下圖:


22222dcd6370.jpg

圖片來源極客時間焰薄,侵刪

可以看到拿诸,索引項是按照我們的定義(姓名,年齡)排好序的塞茅,當我們?nèi)ゲ樵儭畯埲臅r候亩码,他會迅速定位到ID4,然后向后遍歷野瘦;
當然描沟,我們也可以查姓張的人,這樣我們就直接定位到了ID3鞭光,于是這里我們可以看到吏廉,不只是索引的全部定義,只要用到索引的最左N個字段/前綴惰许,就可以加速查詢

5.3 索引下推

索引下推席覆,其實在索引遍歷過程中,對索引包含的字段做判斷啡省,過濾不符合條件的記錄娜睛,減少回表次數(shù)。
比較好玩的是卦睹,Mysql在5.6版本才開始支持該功能畦戒,下推的過程可以看下圖


333333333333c4238c7b65acfe1b.jpg

圖片源自極客時間,侵刪

六结序、建立索引的原則

根據(jù)上面的概念介紹障斋,我們其實可以總結(jié)出,建立索引時要遵循的一些原則:

  • 最左前綴(最高頻的放到最左邊)
  • 索引的復用能力(若調(diào)整字段順序徐鹤,能夠少一個索引垃环,則優(yōu)先使用該順序)
  • 考慮空間和性能
鏈接資源

極客時間 《Mysql實戰(zhàn)》

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市返敬,隨后出現(xiàn)的幾起案子遂庄,更是在濱河造成了極大的恐慌,老刑警劉巖劲赠,帶你破解...
    沈念sama閱讀 211,948評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件涛目,死亡現(xiàn)場離奇詭異,居然都是意外死亡凛澎,警方通過查閱死者的電腦和手機霹肝,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,371評論 3 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來塑煎,“玉大人沫换,你說我怎么就攤上這事∽钐” “怎么了讯赏?”我有些...
    開封第一講書人閱讀 157,490評論 0 348
  • 文/不壞的土叔 我叫張陵垮兑,是天一觀的道長。 經(jīng)常有香客問我漱挎,道長甥角,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,521評論 1 284
  • 正文 為了忘掉前任识樱,我火速辦了婚禮,結(jié)果婚禮上震束,老公的妹妹穿的比我還像新娘怜庸。我一直安慰自己,他們只是感情好垢村,可當我...
    茶點故事閱讀 65,627評論 6 386
  • 文/花漫 我一把揭開白布割疾。 她就那樣靜靜地躺著,像睡著了一般嘉栓。 火紅的嫁衣襯著肌膚如雪宏榕。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,842評論 1 290
  • 那天侵佃,我揣著相機與錄音麻昼,去河邊找鬼。 笑死馋辈,一個胖子當著我的面吹牛抚芦,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播迈螟,決...
    沈念sama閱讀 38,997評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼叉抡,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了答毫?” 一聲冷哼從身側(cè)響起褥民,我...
    開封第一講書人閱讀 37,741評論 0 268
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎洗搂,沒想到半個月后消返,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,203評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡蚕脏,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,534評論 2 327
  • 正文 我和宋清朗相戀三年侦副,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片驼鞭。...
    茶點故事閱讀 38,673評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡秦驯,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出挣棕,到底是詐尸還是另有隱情译隘,我是刑警寧澤亲桥,帶...
    沈念sama閱讀 34,339評論 4 330
  • 正文 年R本政府宣布,位于F島的核電站固耘,受9級特大地震影響题篷,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜厅目,卻給世界環(huán)境...
    茶點故事閱讀 39,955評論 3 313
  • 文/蒙蒙 一番枚、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧损敷,春花似錦葫笼、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,770評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至诱桂,卻和暖如春洋丐,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背挥等。 一陣腳步聲響...
    開封第一講書人閱讀 32,000評論 1 266
  • 我被黑心中介騙來泰國打工友绝, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人肝劲。 一個月前我還...
    沈念sama閱讀 46,394評論 2 360
  • 正文 我出身青樓九榔,卻偏偏與公主長得像,于是被迫代替她去往敵國和親涡相。 傳聞我的和親對象是個殘疾皇子哲泊,可洞房花燭夜當晚...
    茶點故事閱讀 43,562評論 2 349