作者:兜裏有辣條
來源:https://zhuanlan.zhihu.com/p/57359378

學過服務器端開發的朋友一定知道,程序沒有數據庫索引也可以運行。但是所有學習數據庫的資料、教程,一定會有大量的篇幅在介紹數據庫索引,各種後端開發工作的面試也一定繞不開索引,甚至可以說數據庫索引是從後端初級開發跨越到高級開發的屠龍寶刀,那麼索引到底在服務端程序中起着怎樣的作用呢?

這篇文章是一系列數據庫索引文章中的第一篇,這個系列包括了下面四篇文章:

  • 數據庫索引是什麼?新華字典來幫你
  • 數據庫索引融會貫通
  • 20分鐘數據庫索引設計實戰
  • 數據庫索引爲什麼用B+樹實現

這一系列涵蓋了數據庫索引從理論到實踐的一系列知識,一站式解決了從理解到融會貫通的全過程,相信每一篇文章都可以給你帶來更深入的體驗。

什麼是數據庫索引?

用一句話來描述:數據庫索引就是一種加快海量數據查詢的關鍵技術。現在還不理解這句話?不要緊,往下看,20分鐘以後你就能自己做出這樣的總結來了。

首先給大家看一張圖片

數據庫索引是什麼?新華字典來幫你

這本書大家一定都很熟悉,小學入門第一課一定就是教小朋友們學習如何使用這本書。那這和我們的數據庫索引有啥關係呢?彆着急,我們翻開第一頁看看。

數據庫索引是什麼?新華字典來幫你

請大家注意右上角的那一排文字,原來目錄就是傳說中的索引呀!從前面的“一句話描述”我們可以知道,索引的目的就是爲了加快數據查詢。那麼我們查字典時翻的第一個地方是哪裏呢,我相信大部分人都會先翻到拼音目錄,畢竟現在很多人都是提筆忘字了。

數據庫索引的作用和拼音目錄是一樣的,就是最快速的鎖定目標數據所在的位置範圍。比如我們在這裏要查險這個字,那麼我們找到了Xx部分之後就能按順序找到xian這個拼音所在的頁碼,根據前後的頁碼我們可以知道這個字一定是在519頁到523頁之間的,範圍一下子就縮小到只有4頁了。這相比我們從頭翻到尾可是快多了,這時候就出現了第一個專業術語——全表掃描,也就是我們說的從頭找到尾了。

果然,我們在第521頁找到了我們要找的“險”字。

數據庫索引是什麼?新華字典來幫你

那麼現在我們就知道數據庫索引大概是一個什麼東西了:數據庫索引是一個類似於目錄這樣的用來加快數據查詢的技術。

什麼是聯合索引?

相信大家都見過一些包含多個字段的數據庫索引,比如INDEX idx_test(col_a, col_b)。這種包含多個字段的索引就被稱爲“聯合索引”。那麼在多個字段上建索引能起到什麼樣的作用呢?下面還是以新華字典爲例,來看看到底什麼是聯合索引。

新華字典裏還有一種目錄被稱爲“部首目錄”,下面可以看到,要使用這個目錄我們首先會根據部首的筆畫數找到對應該能的部分,然後可以在裏面找到我們想找的部首。比如如果我們還是要找險字所在的位置:

數據庫索引是什麼?新華字典來幫你

找到部首後,右邊的頁碼還不是險字真正的頁碼,我們還需要根據右邊的頁碼找到對應部首在檢字表中的位置。找到第93頁的檢字表後我們就可以根據險字餘下的筆畫數(7畫)在“6-8畫”這一部分裏找到險字真正的頁碼了。

數據庫索引是什麼?新華字典來幫你

在這個過程中,我們按順序使用了“兩個目錄”,一個叫做“部首目錄”,一個叫做“檢字表”。並且我們可以看到上圖中檢字表的內容都是按部首分門別類組織的。這兩個部分合在一起就是我們在本節討論的主題——聯合索引。即通過第一個字段的值(部首)在第一級索引中找到對應的第二級索引位置(檢字表頁碼),然後在第二級索引中根據第二個字段的值(筆畫)找到符合條件的數據所在的位置(險字的真正頁碼)。

最左前綴匹配

從前面使用部首目錄的例子中可以看出,如果我們不知道一個字的部首是什麼的話,那基本是沒辦法使用這個目錄的。這說明僅僅通過筆畫數(第二個字段)是沒辦法使用部首目錄的。

這就引申出了聯合索引的一個規則:聯合索引中的字段,只有某個字段(筆畫)左邊的所有字段(部首)都被使用了,才能使用該字段上的索引。例如,有索引INDEX idx_i1(col_a, col_b),如果查詢條件爲where col_b = 1,則無法使用索引idx_i1。

但是如果我們知道部首但是不知道筆畫數,比如不知道“橫折豎彎勾”是算一筆還是兩筆,那我們仍然可以使用“部首目錄”部分的內容,只是要把“檢字表”對應部首裏的所有字都看一遍就能找到我們要找的字了。

這就引申出了聯合索引的另一個規則:聯合索引中的字段,即使某個字段(部首)右邊的其他字段(筆畫)沒有被使用,該字段之前(含)的所有字段仍然可以正常使用索引。例如,有索引INDEX idx_i2(col_a, col_b, col_c),則查詢條件where col_a = 1 and col_b = 2在字段col_a和col_b上仍然可以走索引。

但是,如果我們在確定部首後,不知道一個字到底是兩畫還是三畫,這種情況下我們只需要在對應部首的兩畫和三畫部分中找就可以了,也就是說我們仍然使用了檢字表中的內容。所以,使用範圍條件查詢時也是可以使用索引的。

最後,我們可以完整地表述一下最左前綴匹配原則的含義:對於一個聯合索引,如果有一個SQL查詢語句需要執行,則只有從索引最左邊的第一個字段開始到SQL語句查詢條件中不包含的字段(不含)或範圍條件字段(含)爲止的部分纔會使用索引進行加速。

這裏出現了一個之前沒有提到的點,就是範圍條件字段也會結束對索引上後續字段的使用,這是爲什麼呢?具體原因的解釋涉及到了更深層次的知識,在接下來的第二篇文章的最後就可以找到答案。

什麼是聚集索引?

從上文的部首目錄和拼音目錄同時存在但是實際的字典內容只有一份這一點上可以看出,在數據庫中一張表上是可以有多個索引的。那麼不同的索引之間有什麼區別呢?

我們在新華字典的側面可以看到一個V字形的一個個黑色小方塊,有很多人都會在側面寫上A, B, C, D這樣對應的拼音字母。因爲字典中所有的字都是按照拼音順序排列的,有時候直接使用首字母翻開對應的部分查也很快。

數據庫索引是什麼?新華字典來幫你

像拼音目錄這樣的索引,數據會根據索引中的順序進行排列和組織的,這樣的索引就被稱爲聚集索引,而非聚集索引就是其他的一般索引。因爲數據只能按照一種規則排序,所以一張表至多有一個聚集索引,但可以有多個非聚集索引。

在MySQL數據庫的InnoDB存儲引擎中,主鍵索引就是聚集索引,所有數據都會按照主鍵索引進行組織;而在MyISAM存儲引擎中,就沒有聚集索引了,因爲MyISAM存儲引擎中的數據不是按索引順序進行存儲的。

34張架構史上最全技術知識圖譜

相關文章