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

引入


  • 場(chǎng)景
    假設(shè)我們有一個(gè)數(shù)據(jù)庫(kù)表 Employee, 這個(gè)表有三個(gè)字段(列)分別是 Employee_Name仙蚜、Employee_Age 和Employee_Address主卫。假設(shè)表Employee 有上千行數(shù)據(jù)忠怖。
    現(xiàn)在假設(shè)我們要從這個(gè)表中查找出所有名字是‘Jesus’的雇員信息。我們決定使用下面的查詢語(yǔ)句:
SELECT * FROM Employee WHERE Employee_Name = 'Jesus'
  • 問(wèn)題
    如果表中沒(méi)有所以會(huì)發(fā)生什么屿聋?一旦我們運(yùn)行這個(gè)查詢,在查找名字為Jesus的雇員的過(guò)程中藏鹊,究竟會(huì)發(fā)生什么胜臊?
    數(shù)據(jù)庫(kù)不得不Employee表中的每一行并確定雇員的名字(Employee_Name)是否為 ‘Jesus’。由于我們想要得到每一個(gè)名字為Jesus的雇員信息伙判,在查詢到第一個(gè)符合條件的行后象对,不能停止查詢,因?yàn)榭赡苓€有其他符合條件的行宴抚。所以勒魔,必須一行一行的查找直到最后一行-這就意味數(shù)據(jù)庫(kù)不得不檢查上千行數(shù)據(jù)才能找到所以名字為Jesus的雇員。這就是所謂的全表掃描菇曲。

常用索引介紹

  • 數(shù)據(jù)庫(kù)索引是怎樣提升性能的冠绢?
    你可能會(huì)想為如此簡(jiǎn)單的事情做全表掃描效率欠佳-數(shù)據(jù)庫(kù)是不是應(yīng)該更聰明一點(diǎn)呢?這就像用人眼從頭到尾瀏覽整張表-很慢也不優(yōu)雅(原文:not at all sleek常潮,不知如何翻譯才好)弟胀。但是,你可以能根據(jù)文章標(biāo)題已經(jīng)猜到,這就是索引派上用場(chǎng)的時(shí)候孵户。使用索引的全部意義就是通過(guò)縮小一張表中需要查詢的記錄/行的數(shù)目來(lái)加快搜索的速度萧朝。

  • 什么是索引?
    一個(gè)索引是存儲(chǔ)的表中一個(gè)特定列的值數(shù)據(jù)結(jié)構(gòu)(最常見(jiàn)的是B-Tree)夏哭。索引是在表的列上創(chuàng)建检柬。所以,要記住的關(guān)鍵點(diǎn)是索引包含一個(gè)表中列的值竖配,并且這些值存儲(chǔ)在一個(gè)數(shù)據(jù)結(jié)構(gòu)中何址。請(qǐng)記住記住這一點(diǎn):索引是一種數(shù)據(jù)結(jié)構(gòu)

  • 什么樣的數(shù)據(jù)結(jié)構(gòu)可以作為索引进胯?
    B-Tree是最常用的用于索引的數(shù)據(jù)結(jié)構(gòu)用爪。因?yàn)樗鼈兪菚r(shí)間復(fù)雜度低, 查找胁镐、刪除项钮、插入操作都可以可以在對(duì)數(shù)時(shí)間內(nèi)完成。另外一個(gè)重要原因存儲(chǔ)在B-Tree中的數(shù)據(jù)是有序的希停。數(shù)據(jù)庫(kù)管理系統(tǒng)(RDBMS)通常決定索引應(yīng)該用哪些數(shù)據(jù)結(jié)構(gòu)烁巫。但是,在某些情況下宠能,你在創(chuàng)建索引時(shí)可以指定索引要使用的數(shù)據(jù)結(jié)構(gòu)亚隙。

  • 哈希表索引是怎么工作的?
    哈希表是另外一種你可能看到用作索引的數(shù)據(jù)結(jié)構(gòu)-這些索引通常被稱為哈希索引违崇。使用哈希索引的原因是阿弃,在尋找值時(shí)哈希表效率極高。所以羞延,如果使用哈希索引渣淳,對(duì)于比較字符串是否相等的查詢能夠極快的檢索出的值。例如之前我們討論過(guò)的這個(gè)查詢(SELECT * FROM Employee WHERE Employee_Name = ‘Jesus’) 就可以受益于創(chuàng)建在Employee_Name 列上的哈希索引伴箩。哈系索引的工作方式是將列的值作為索引的鍵值(key)入愧,和鍵值相對(duì)應(yīng)實(shí)際的值(value)是指向該表中相應(yīng)行的指針。因?yàn)楣1砘旧峡梢钥醋魇顷P(guān)聯(lián)數(shù)組嗤谚,一個(gè)典型的數(shù)據(jù)項(xiàng)就像“Jesus => 0x28939″棺蛛,而0x28939是對(duì)內(nèi)存中表中包含Jesus這一行的引用。在哈系索引的中查詢一個(gè)像“Jesus”這樣的值巩步,并得到對(duì)應(yīng)行的在內(nèi)存中的引用旁赊,明顯要比掃描全表獲得值為“Jesus”的行的方式快很多。

  • 哈希索引的缺點(diǎn)
    哈希表是無(wú)順的數(shù)據(jù)結(jié)構(gòu)椅野,對(duì)于很多類型的查詢語(yǔ)句哈希索引都無(wú)能為力终畅。舉例來(lái)說(shuō)籍胯,假如你想要找出所有小于40歲的員工。你怎么使用使用哈希索引進(jìn)行查詢离福?這不可行杖狼,因?yàn)楣1碇贿m合查詢鍵值對(duì)-也就是說(shuō)查詢相等的查詢(例:like “WHERE name = ‘Jesus’)。哈希表的鍵值映射也暗示其鍵的存儲(chǔ)是無(wú)序的术徊。這就是為什么哈希索引通常不是數(shù)據(jù)庫(kù)索引的默認(rèn)數(shù)據(jù)結(jié)構(gòu)-因?yàn)樵谧鳛樗饕臄?shù)據(jù)結(jié)構(gòu)時(shí),其不像B-Tree那么靈活

  • 還有什么其他類型的索引鲸湃?
    使用R-Tree作為數(shù)據(jù)結(jié)構(gòu)的索引通常用來(lái)為空間問(wèn)題提供幫助赠涮。例如,一個(gè)查詢要求“查詢出所有距離我兩公里之內(nèi)的星巴克”暗挑,如果數(shù)據(jù)庫(kù)表使用R- Tree索引笋除,這類查詢的效率將會(huì)提高。
    另一種索引是位圖索引(bitmap index)炸裆, 這類索引適合放在包含布爾值(true 和 false)的列上垃它,但是這些值(表示true或false的值)的許多實(shí)例-基本上都是選擇性(selectivity)低的列。

索引的本質(zhì)

  • 索引是怎么提升性能的烹看?
    因?yàn)樗饕旧鲜怯脕?lái)存儲(chǔ)列值的數(shù)據(jù)結(jié)構(gòu)国拇,這使查找這些列值更加快速。如果索引使用最常用的數(shù)據(jù)結(jié)構(gòu)-B-Tree-那么其中的數(shù)據(jù)是有序的惯殊。有序的列值可以極大的提升性能酱吝。下面解釋原因。
    假設(shè)我們?cè)?Employee_Name這一列上創(chuàng)建一個(gè)B-Tree索引土思。這意味著當(dāng)我們用之前的SQL查找姓名是‘Jesus’的雇員時(shí)务热,不需要再掃描全表,【只需要在B-Tree中查找】己儒。而是用索引查找去查找名字為‘Jesus’的雇員崎岂,因?yàn)樗饕呀?jīng)按照按字母順序排序。索引已經(jīng)排序意味著查詢一個(gè)名字會(huì)快很多闪湾,因?yàn)槊稚僮帜笧椤甁’的員工都是排列在一起的冲甘。另外重要的一點(diǎn)是,索引同時(shí)存儲(chǔ)了表中相應(yīng)行的指針以獲取其他列的數(shù)據(jù)途样。

  • 數(shù)據(jù)庫(kù)索引里究竟存的是什么损合?
    你現(xiàn)在已經(jīng)知道數(shù)據(jù)庫(kù)索引是創(chuàng)建在表的某列上的,并且存儲(chǔ)了這一列的所有值娘纷。但是嫁审,需要理解的重點(diǎn)是數(shù)據(jù)庫(kù)索引并不存儲(chǔ)這個(gè)表中其他列(字段)的值。舉例來(lái)說(shuō)赖晶,如果我們?cè)贓mployee_Name列創(chuàng)建索引律适,那么列Employee_Age和Employee_Address上的值并不會(huì)存儲(chǔ)在這個(gè)索引當(dāng)中辐烂。如果我們確實(shí)把其他所有字段也存儲(chǔ)在個(gè)這個(gè)索引中,那就成了拷貝一整張表做為索引-這樣會(huì)占用太大的空間而且會(huì)十分低效捂贿。

  • 索引存儲(chǔ)了指向表中某一行的指針
    如果我們?cè)谒饕镎业侥骋粭l記錄作為索引的列的值纠修,如何才能找到這一條記錄的其它值呢?這是很簡(jiǎn)單 - 數(shù)據(jù)庫(kù)索引同時(shí)存儲(chǔ)了指向表中的相應(yīng)行的指針厂僧。指針是指一塊內(nèi)存區(qū)域扣草, 該內(nèi)存區(qū)域記錄的是對(duì)硬盤(pán)上記錄的相應(yīng)行的數(shù)據(jù)的引用。因此颜屠,索引中除了存儲(chǔ)列的值辰妙,還存儲(chǔ)著一個(gè)指向在行數(shù)據(jù)的索引。也就是說(shuō)甫窟,索引中的Employee_Name這列的某個(gè)值(或者節(jié)點(diǎn))可以描述為 (“Jesus”, 0x82829)密浑, 0x82829 就是包含 “Jesus”那行數(shù)據(jù)在硬盤(pán)上的地址。如果沒(méi)有這個(gè)引用粗井,你就只能訪問(wèn)到一個(gè)單獨(dú)的值(“Jesus”)尔破,而這樣沒(méi)有意義,因?yàn)槟悴荒塬@取這一行記錄的employee的其他值-例如地址(address)和年齡(age)浇衬。

  • 數(shù)據(jù)庫(kù)怎么知道什么時(shí)候使用索引懒构?
    當(dāng)這個(gè)SQL (SELECT * FROM Employee WHERE Employee_Name = ‘Jesus’ )運(yùn)行時(shí),數(shù)據(jù)庫(kù)會(huì)檢查在查詢的列上是否有索引耘擂。假設(shè)Employee_Name列上確實(shí)創(chuàng)建了索引痴脾,數(shù)據(jù)庫(kù)會(huì)接著檢查使用這個(gè)索引做查詢是否合理 - 因?yàn)橛行﹫?chǎng)景下,使用索引比起全表掃描會(huì)更加低效梳星。如果想要了解更多這些場(chǎng)景赞赖,請(qǐng)閱讀這篇文章:Selectivity in SQL

  • 你能強(qiáng)制數(shù)據(jù)庫(kù)使用索引嗎?
    通常來(lái)說(shuō)冤灾, 你不會(huì)告訴數(shù)據(jù)庫(kù)什么時(shí)候使用索引 - 數(shù)據(jù)庫(kù)自己決定前域。然而,值得注意的是在大多數(shù)數(shù)據(jù)庫(kù)中(像Oracle 和 MYSQL)韵吨, 你實(shí)際上可以制訂你想要使用的索引匿垄。

  • 如何在使用SQL創(chuàng)建索引:
    之前的例子中,在Employee_Name列上創(chuàng)建索引的SQL如下:

CREATE  INDEX name_index ON Employee (Employee_Name)
  • 如何創(chuàng)建聯(lián)合索引
    我們可以在雇員表上創(chuàng)建兩個(gè)列的聯(lián)合索引归粉,SQL如下:
CREATE  INDEX name_index ON Employee (Employee_Name, Employee_Age)
  • 把數(shù)據(jù)庫(kù)索引類比成什么比較好呢?
    一個(gè)非常好的類比是把數(shù)據(jù)庫(kù)索引看作是書(shū)的索引椿疗。如果你有一本關(guān)于狗的書(shū),你想要找關(guān)于‘黃金獵犬’的那部分糠悼。當(dāng)你可以通過(guò)在書(shū)背的索引找到哪幾頁(yè)有關(guān)于‘黃金獵犬’信息的時(shí)候届榄,你為什么要翻完正本書(shū) - 這相當(dāng)于數(shù)據(jù)庫(kù)中的全表掃描。同樣的倔喂,就像一本書(shū)的索引包含頁(yè)碼一樣铝条,數(shù)據(jù)庫(kù)的索引包含了指針靖苇,指向你在SQL中想要查詢的值所在的行。

  • 使用數(shù)據(jù)庫(kù)索引會(huì)有什么代價(jià)班缰?
    那么贤壁,使用數(shù)據(jù)庫(kù)索引有什么缺點(diǎn)呢?其一埠忘,索引會(huì)占用空間 - 你的表越大脾拆,索引占用的空間越大。其二莹妒,性能損失(主要值更新操作)名船,當(dāng)你在表中添加、刪除或者更新行數(shù)據(jù)的時(shí)候动羽, 在索引中也會(huì)有相同的操作包帚。記子嫫凇:建立在某列(或多列)索引需要保存該列最新的數(shù)據(jù)运吓。

基本原則:是只如果表中某列在查詢過(guò)程中使用的非常頻繁,那就在該列上創(chuàng)建索引疯趟。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末拘哨,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子信峻,更是在濱河造成了極大的恐慌倦青,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,265評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件盹舞,死亡現(xiàn)場(chǎng)離奇詭異产镐,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)踢步,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,078評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門(mén)癣亚,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人获印,你說(shuō)我怎么就攤上這事述雾。” “怎么了兼丰?”我有些...
    開(kāi)封第一講書(shū)人閱讀 156,852評(píng)論 0 347
  • 文/不壞的土叔 我叫張陵玻孟,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我鳍征,道長(zhǎng)黍翎,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,408評(píng)論 1 283
  • 正文 為了忘掉前任艳丛,我火速辦了婚禮玩敏,結(jié)果婚禮上斗忌,老公的妹妹穿的比我還像新娘。我一直安慰自己旺聚,他們只是感情好织阳,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,445評(píng)論 5 384
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著砰粹,像睡著了一般唧躲。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上碱璃,一...
    開(kāi)封第一講書(shū)人閱讀 49,772評(píng)論 1 290
  • 那天弄痹,我揣著相機(jī)與錄音,去河邊找鬼嵌器。 笑死肛真,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的爽航。 我是一名探鬼主播蚓让,決...
    沈念sama閱讀 38,921評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼讥珍!你這毒婦竟也來(lái)了历极?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 37,688評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤衷佃,失蹤者是張志新(化名)和其女友劉穎趟卸,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體氏义,經(jīng)...
    沈念sama閱讀 44,130評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡锄列,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,467評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了惯悠。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片邻邮。...
    茶點(diǎn)故事閱讀 38,617評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖吮螺,靈堂內(nèi)的尸體忽然破棺而出饶囚,到底是詐尸還是另有隱情,我是刑警寧澤鸠补,帶...
    沈念sama閱讀 34,276評(píng)論 4 329
  • 正文 年R本政府宣布萝风,位于F島的核電站,受9級(jí)特大地震影響紫岩,放射性物質(zhì)發(fā)生泄漏规惰。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,882評(píng)論 3 312
  • 文/蒙蒙 一泉蝌、第九天 我趴在偏房一處隱蔽的房頂上張望歇万。 院中可真熱鬧揩晴,春花似錦、人聲如沸贪磺。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,740評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)寒锚。三九已至劫映,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間刹前,已是汗流浹背泳赋。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,967評(píng)論 1 265
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留喇喉,地道東北人祖今。 一個(gè)月前我還...
    沈念sama閱讀 46,315評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像拣技,于是被迫代替她去往敵國(guó)和親千诬。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,486評(píng)論 2 348

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

  • 對(duì)于數(shù)據(jù)庫(kù)的優(yōu)化主要包括三個(gè)部分:查詢優(yōu)化过咬、索引優(yōu)化和字段類型優(yōu)化大渤,其中制妄,索引優(yōu)化則是數(shù)據(jù)庫(kù)優(yōu)化的重中之重掸绞。一個(gè)查...
    charming_coder閱讀 4,281評(píng)論 1 18
  • 索引的基本原理,以及數(shù)據(jù)是如何被訪問(wèn)的 (一)SQLS如何訪問(wèn)沒(méi)有建立索引的數(shù)據(jù)表 Heap譯成漢語(yǔ)叫做“堆”耕捞,其...
    安易學(xué)車閱讀 3,441評(píng)論 0 8
  • 基本介紹 數(shù)據(jù)庫(kù)索引好比是一本書(shū)前面的目錄衔掸,能加快數(shù)據(jù)庫(kù)的查詢速度。 例如這樣一個(gè)查詢:select * from...
    安易學(xué)車閱讀 1,318評(píng)論 0 6
  • 先由一個(gè)例子來(lái)引入索引: 假設(shè)有一張表Users俺抽,三個(gè)字段分別是user_name敞映,user_age,user_s...
    cwjbest閱讀 261評(píng)論 0 0
  • 我家房后不遠(yuǎn)處有一條專門(mén)搞運(yùn)輸?shù)蔫F路線磷斧,緊挨著鐵道的地方還有一個(gè)小型煤場(chǎng)振愿,煤場(chǎng)入口的鐵道上有兩扇大鐵門(mén),平時(shí)一直是...
    北斗夜涼閱讀 460評(píng)論 0 0