學過服務器端開發(fā)的朋友一定知道,程序沒有數據庫索引也可以運行凤藏。但是所有學習數據庫的資料奸忽、教程,一定會有大量的篇幅在介紹數據庫索引揖庄,各種后端開發(fā)工作的面試也一定繞不開索引栗菜,甚至可以說數據庫索引是從后端初級開發(fā)跨越到高級開發(fā)的屠龍寶刀,那么索引到底在服務端程序中起著怎樣的作用呢蹄梢?
這篇文章是一系列數據庫索引文章中的第一篇疙筹,這個系列包括了下面四篇文章:
數據庫索引是什么?新華字典來幫你 —— 理解
數據庫索引融會貫通 —— 深入
20分鐘數據庫索引設計實戰(zhàn) —— 實戰(zhàn)
數據庫索引為什么用B+樹實現禁炒? —— 擴展
這一系列涵蓋了數據庫索引從理論到實踐的一系列知識而咆,一站式解決了從理解到融會貫通的全過程,相信每一篇文章都可以給你帶來更深入的體驗幕袱。
什么是數據庫索引暴备?
用一句話來描述:數據庫索引就是一種加快海量數據查詢的關鍵技術。現在還不理解這句話们豌?不要緊涯捻,往下看,20分鐘以后你就能自己做出這樣的總結來了望迎。
首先給大家看一張圖片
這本書大家一定都很熟悉汰瘫,小學入門第一課一定就是教小朋友們學習如何使用這本書。那這和我們的數據庫索引有啥關系呢擂煞?別著急混弥,我們翻開第一頁看看。
請大家注意右上角的那一排文字对省,原來目錄就是傳說中的索引呀蝗拿!從前面的“一句話描述”我們可以知道,索引的目的就是為了加快數據查詢蒿涎。那么我們查字典時翻的第一個地方是哪里呢哀托,我相信大部分人都會先翻到拼音目錄,畢竟現在很多人都是提筆忘字了??劳秋。
數據庫索引的作用和拼音目錄是一樣的仓手,就是最快速的鎖定目標數據所在的位置范圍胖齐。比如我們在這里要查險
這個字,那么我們找到了Xx
部分之后就能按順序找到xian
這個拼音所在的頁碼嗽冒,根據前后的頁碼我們可以知道這個字一定是在519頁到523頁之間的呀伙,范圍一下子就縮小到只有4頁了。這相比我們從頭翻到尾可是快多了添坊,這時候就出現了第一個專業(yè)術語——全表掃描剿另,也就是我們說的從頭找到尾了。
果然贬蛙,我們在第521頁找到了我們要找的“險”字雨女。
那么現在我們就知道數據庫索引大概是一個什么東西了:數據庫索引是一個類似于目錄這樣的用來加快數據查詢的技術。
什么是聯合索引阳准?
相信大家都見過一些包含多個字段的數據庫索引氛堕,比如INDEX idx_test(col_a, col_b)
。這種包含多個字段的索引就被稱為“聯合索引”野蝇。那么在多個字段上建索引能起到什么樣的作用呢讼稚?下面還是以新華字典為例,來看看到底什么是聯合索引浪耘。
新華字典里還有一種目錄被稱為“部首目錄”,下面可以看到塑崖,要使用這個目錄我們首先會根據部首的筆畫數找到對應該能的部分七冲,然后可以在里面找到我們想找的部首。比如如果我們還是要找險
字所在的位置:
找到部首后规婆,右邊的頁碼還不是險
字真正的頁碼澜躺,我們還需要根據右邊的頁碼找到對應部首在檢字表中的位置。找到第93頁的檢字表后我們就可以根據險
字余下的筆畫數(7畫)在“6-8畫”這一部分里找到險
字真正的頁碼了抒蚜。
在這個過程中掘鄙,我們按順序使用了“兩個目錄”,一個叫做“部首目錄”嗡髓,一個叫做“檢字表”操漠。并且我們可以看到上圖中檢字表的內容都是按部首分門別類組織的。這兩個部分合在一起就是我們在本節(jié)討論的主題——聯合索引饿这。即通過第一個字段的值(部首)在第一級索引中找到對應的第二級索引位置(檢字表頁碼)浊伙,然后在第二級索引中根據第二個字段的值(筆畫)找到符合條件的數據所在的位置(險
字的真正頁碼)。
最左前綴匹配
從前面使用部首目錄的例子中可以看出长捧,如果我們不知道一個字的部首是什么的話嚣鄙,那基本是沒辦法使用這個目錄的。這說明僅僅通過筆畫數(第二個字段)是沒辦法使用部首目錄的串结。
這就引申出了聯合索引的一個規(guī)則:聯合索引中的字段哑子,只有某個字段(筆畫)左邊的所有字段(部首)都被使用了舅列,才能使用該字段上的索引。例如卧蜓,有索引INDEX idx_i1(col_a, col_b)
帐要,如果查詢條件為where col_b = 1
,則無法使用索引idx_i1
烦却。
但是如果我們知道部首但是不知道筆畫數宠叼,比如不知道“橫折豎彎勾”是算一筆還是兩筆,那我們仍然可以使用“部首目錄”部分的內容其爵,只是要把“檢字表”對應部首里的所有字都看一遍就能找到我們要找的字了冒冬。
這就引申出了聯合索引的另一個規(guī)則:聯合索引中的字段,即使某個字段(部首)右邊的其他字段(筆畫)沒有被使用摩渺,該字段之前(含)的所有字段仍然可以正常使用索引简烤。例如,有索引INDEX idx_i2(col_a, col_b, col_c)
摇幻,則查詢條件where col_a = 1 and col_b = 2
在字段col_a
和col_b
上仍然可以走索引横侦。
但是,如果我們在確定部首后绰姻,不知道一個字到底是兩畫還是三畫枉侧,這種情況下我們只需要在對應部首的兩畫和三畫部分中找就可以了,也就是說我們仍然使用了檢字表中的內容狂芋。所以榨馁,使用范圍條件查詢時也是可以使用索引的。
最后帜矾,我們可以完整地表述一下最左前綴匹配原則的含義:對于一個聯合索引翼虫,如果有一個SQL查詢語句需要執(zhí)行,則只有從索引最左邊的第一個字段開始到SQL語句查詢條件中不包含的字段(不含)或范圍條件字段(含)為止的部分才會使用索引進行加速屡萤。
這里出現了一個之前沒有提到的點珍剑,就是范圍條件字段也會結束對索引上后續(xù)字段的使用,這是為什么呢死陆?具體原因的解釋涉及到了更深層次的知識招拙,在接下來的第二篇文章的最后就可以找到答案。
什么是聚集索引措译?
從上文的部首目錄和拼音目錄同時存在但是實際的字典內容只有一份這一點上可以看出迫像,在數據庫中一張表上是可以有多個索引的。那么不同的索引之間有什么區(qū)別呢瞳遍?
我們在新華字典的側面可以看到一個V字形的一個個黑色小方塊闻妓,有很多人都會在側面寫上A, B, C, D
這樣對應的拼音字母。因為字典中所有的字都是按照拼音順序排列的掠械,有時候直接使用首字母翻開對應的部分查也很快由缆。
像拼音目錄這樣的索引注祖,數據會根據索引中的順序進行排列和組織的,這樣的索引就被稱為聚集索引均唉,而非聚集索引就是其他的一般索引是晨。因為數據只能按照一種規(guī)則排序,所以一張表至多有一個聚集索引舔箭,但可以有多個非聚集索引罩缴。
在MySQL數據庫的InnoDB
存儲引擎中,主鍵索引就是聚集索引层扶,所有數據都會按照主鍵索引進行組織箫章;而在MyISAM
存儲引擎中,就沒有聚集索引了镜会,因為MyISAM存儲引擎中的數據不是按索引順序進行存儲的檬寂。