如何通過索引提高數(shù)據(jù)庫檢索的效率

如何通過索引提高數(shù)據(jù)庫檢索的效率

這是前幾天同事做的技術(shù)分析块仆,講的挺不錯脐彩,現(xiàn)在整理一下

本文中數(shù)據(jù)庫操作與數(shù)據(jù)庫工作原理描述徙歼,都是經(jīng)過簡化的犁河,實際應(yīng)用中鳖枕,數(shù)據(jù)庫本身也會提供各種優(yōu)化措施。

數(shù)據(jù)庫線性搜索

假設(shè)現(xiàn)在又一個幾百萬條數(shù)據(jù)的購物車銷售記錄表桨螺,表結(jié)構(gòu)類似下表

id userid productid dealdate promotions dealstate
1 10876 100003 14567776667 -9.5 成交
2 93772 188293 14566636777 -8 關(guān)閉

Q1: 查詢 userid = 100003 的用戶宾符,所有購買記錄。

A1: 在沒有做任何優(yōu)化的情況下灭翔,數(shù)據(jù)庫需要從 id = 1 的記錄開始向下掃描魏烫,直到將整個?表掃描完畢,才可以檢索出所有?符合要求的記錄缠局。?可想而知则奥,當(dāng)表中記錄非常多的時候,需要?非常多的磁盤 I/O 才能完成此次查詢狭园。在實際應(yīng)用中读处,例如 x 東用戶查詢自己的購買記錄這種需求,對服務(wù)器來說就是災(zāi)難啊唱矛。

使用索引提高查詢效率

使用?單個字段建立索引

回到 Q1 這個問題罚舱,如果我們在 userid 這個字段上建立索引,那么會產(chǎn)生一個 userid 到?記錄位置的映射绎谦。?這也是一個?表管闷,在這個表中?查找某個 userid,就能夠找到所有符合該 userid ?的記錄在表中的位置窃肠,然后直接訪問這些位置讀取記錄就可以了包个。

使用多個字段建立索引

?Q2: 如果遇到一個購物達(dá)人,購物記錄有上萬條冤留,通過 userid 這個索引查詢該用戶的所有搜索記錄碧囊,就?會產(chǎn)生上萬次磁盤 I/O,如果是機(jī)械硬盤纤怒,單單是尋道時間就?把這次查詢卡爆了糯而,即使換 SSD,能夠服務(wù)的用戶?也是很有限的泊窘。

A2: ?遇到這種情況熄驼,我們可以將該用戶的購物記錄分頁,每次返回十幾條展示出來就可以了烘豹。向后翻頁的時候瓜贾,可以從 offset 開始,再檢索出十幾條返回到前端展示携悯。特別是移動端與桌面端?可能會跳到第10頁這種需求不同祭芦,向來都是上拉加載更多,是線性加載的蚌卤,?對數(shù)據(jù)庫壓力就更小了实束。(PS. 跳轉(zhuǎn)到第幾頁這種需求奥秆,需要 count 數(shù)據(jù)的總數(shù),通常情況下咸灿,這個操作也需要將所有記錄讀取一遍构订,效率很低。)
這種需求下避矢,一般會將購物記錄按照時間順序返回給用戶悼瘾,我們只需要用 userid 和 dealdate 這兩個字段建立一個復(fù)合索引{userid,dealdate}就可以了审胸。(建立索引時亥宿,指定 dealdate 按照降序排列)
檢索時,查找“近一月購物記錄”砂沛,只要按照時間檢索一些數(shù)據(jù)出來就可以了烫扼。

不應(yīng)該建立?什么樣的索引

如果?我們需要查詢成交狀態(tài),是不是可以?建立一個{dealstate}這樣的索引呢碍庵?
答案是映企,沒什么用。
如果檢索 dealstate = 成交 這樣的記錄静浴,如果掃描整個表堰氓,需要檢索的記錄是 500?w 條。建立索引后苹享,檢索的記錄也就減到 100w-200w 條双絮。

這種優(yōu)化,并沒有數(shù)量級上的優(yōu)化效果得问,還需要占用大量空間囤攀,這種“優(yōu)化”一般認(rèn)為是沒有意義的。

對于值為 bool 型或 enum? 型的字段椭赋,通常不建立索引抚岗。

建立索引的兩種原理

索引到數(shù)據(jù)映射一般有兩種實現(xiàn)方式或杠,一種是 hash?哪怔,這個沒有排序的能力,另一種是? B 樹或 B+ 樹向抢,這個有排序的能力认境。

如何快速從索引中檢索相應(yīng)的值

通常情況下,會選擇 B 樹或者 B+ 樹實現(xiàn)索引挟鸠,以獲得排序的能力叉信。

B+ 樹

從 B+ 樹的數(shù)據(jù)結(jié)構(gòu)來看,?解決 ?Q2? 這個問題艘希,例如要檢索上個月購物記錄硼身,只要 logN 的時間就能查詢到相應(yīng)的記錄硅急。

B+ 樹在 logN 時間內(nèi)就可以完成查找

?并且從上圖可以看到,B+ 樹的各個節(jié)點之間佳遂,都通過指針進(jìn)行連接营袜,從當(dāng)前指向的數(shù)據(jù)出發(fā),向后查找數(shù)據(jù)是非常方便和快速的丑罪。能完美的實現(xiàn)上拉加載更多這種需求荚板。

應(yīng)該如何建立復(fù)合索引

如果對本文開頭的表,建立一個復(fù)合索引吩屹,同時查詢購買時間跪另、購物折扣等,可以?這樣建立復(fù)合索引煤搜。
{ productid(升序)免绿,promotions(升序), dealdate(降序)}
這里擦盾,雖然對 productid 進(jìn)行排序沒有現(xiàn)實意義针姿,但是在計算機(jī)看來,依然是可以排序的厌衙。
在建立? B+ 樹時距淫,先比較 productid,再比較 promotions婶希,最后比較? dealdate榕暇,并且按照比較結(jié)果?生成一顆 B+ 樹。

那么查找的時候喻杈,如果檢索的內(nèi)容是:{productid}彤枢,索引是有效的。

如果?檢索的內(nèi)容是:{ productid(升序)筒饰、dealdate(降序)} 那么索引也是有效的缴啡,比較的時候,promotions 不比較(永遠(yuǎn)==)就可以了瓷们。

如果檢索的內(nèi)容是:{ productid(升序)业栅、 dealdate(降序)、promotions(升序)} 這時候谬晕,索引就無效了碘裕。因為此時的比較條件,與生存索引時的比較條件不一致(生成索引時攒钳,productid 相同的情況下帮孔,比較 promotions 的大小,此時 productid 相同的情況下不撑,比較 dealdate 的大小文兢。)

如果檢索的內(nèi)容是:{ productid(升序)晤斩、dealdate(升序)} 索引也是無效的。此時比較的條件姆坚,也與索引生成時不一致尸昧。

從上文就可以看出,建立數(shù)據(jù)庫索引時旷偿,就要考慮檢索條件才行

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末烹俗,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子萍程,更是在濱河造成了極大的恐慌幢妄,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,755評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件茫负,死亡現(xiàn)場離奇詭異蕉鸳,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)忍法,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評論 3 395
  • 文/潘曉璐 我一進(jìn)店門潮尝,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人饿序,你說我怎么就攤上這事勉失。” “怎么了原探?”我有些...
    開封第一講書人閱讀 165,138評論 0 355
  • 文/不壞的土叔 我叫張陵乱凿,是天一觀的道長。 經(jīng)常有香客問我咽弦,道長徒蟆,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,791評論 1 295
  • 正文 為了忘掉前任型型,我火速辦了婚禮段审,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘闹蒜。我一直安慰自己寺枉,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,794評論 6 392
  • 文/花漫 我一把揭開白布嫂用。 她就那樣靜靜地躺著型凳,像睡著了一般丈冬。 火紅的嫁衣襯著肌膚如雪嘱函。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,631評論 1 305
  • 那天埂蕊,我揣著相機(jī)與錄音往弓,去河邊找鬼疏唾。 笑死,一個胖子當(dāng)著我的面吹牛函似,可吹牛的內(nèi)容都是我干的槐脏。 我是一名探鬼主播,決...
    沈念sama閱讀 40,362評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼撇寞,長吁一口氣:“原來是場噩夢啊……” “哼顿天!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起蔑担,我...
    開封第一講書人閱讀 39,264評論 0 276
  • 序言:老撾萬榮一對情侶失蹤牌废,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后啤握,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體鸟缕,經(jīng)...
    沈念sama閱讀 45,724評論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年排抬,在試婚紗的時候發(fā)現(xiàn)自己被綠了懂从。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,040評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡蹲蒲,死狀恐怖番甩,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情届搁,我是刑警寧澤对室,帶...
    沈念sama閱讀 35,742評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站咖祭,受9級特大地震影響掩宜,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜么翰,卻給世界環(huán)境...
    茶點故事閱讀 41,364評論 3 330
  • 文/蒙蒙 一牺汤、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧浩嫌,春花似錦檐迟、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,944評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至骚腥,卻和暖如春敦间,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,060評論 1 270
  • 我被黑心中介騙來泰國打工廓块, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留厢绝,地道東北人。 一個月前我還...
    沈念sama閱讀 48,247評論 3 371
  • 正文 我出身青樓带猴,卻偏偏與公主長得像昔汉,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子拴清,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,979評論 2 355

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