什麼是索引,索引說白了就是一種提高查詢效率的資料結構,mysql底層是用b+tree來實現的
分析b+tree之前,我們先來看下其他的幾種資料結構之間的區別以及mysql為什麼底層是選擇用b+tree來實現索引的
這邊網上看到一篇介紹資料結構的,可以參考
常見的幾種索引資料結構
1.二叉樹
2.紅黑樹
3.hash表
4.b-tree
1.我們首先來看下二叉樹:
這是乙個典型的二叉樹的資料結構,每個結點都只有2個字節點,我們可以看到,當資料不斷的增加的時候,樹的高度就會不斷增加,他查詢的複雜度就是樹的高度,每次查詢都會與磁碟做一次i/o互動,消耗比較大。
2.紅黑樹:
紅黑樹不斷新增資料的時候,樹的結點會發生乙個自旋,關於紅黑樹的資料結構比較複雜,這裡先不做介紹,之後可能會更新新的部落格做介紹,但是能看到每個結點也只有2個字節點,樹的高度也會隨著資料的增加不斷的增加。
3.hash表
hash表是一種key-value的資料結構,它是將 key 通過乙個雜湊函式計算出乙個數字,然後以該數字作為陣列的下標,然後將 value 存放到對應下標的陣列中。hash表可能出現的問題
1.對於不同的 key,在經過雜湊函式計算後,可能出現相同的值,就有可能出現雜湊碰撞,這時候就意味著同乙個陣列下標處要存放兩個元素了,所以這個時候將陣列中的元素變為乙個鍊錶,通過鍊錶將這兩個元素串聯起來
2.hash表只適合等值查詢,如果遇到範圍查詢等,效率就會很低,不符合實際工作場景
4.b-tree
b-tree 的特點是無論葉子結點和非葉子結點,它都存有索引值和資料;b+tree 的特點是只有葉子結點才會存放索引值和資料,非葉子結點只會存放索引值本身。因此對於非葉子結點,乙個結點中,b+tree 存放的索引值數量會遠遠大於 b-tree(因為乙個結點的空間是有限的,b-tree 要存放索引+資料,而 b+tree 只需要存放索引),這樣就導致了每個結點中,b+tree 能向下分出更多的叉,子結點數更多。
那麼在要儲存同樣大小的資料檔案的場景下,用 b+tree 儲存,最終樹的高度會遠遠小於用 b-tree 儲存的高度,所以使用 b+tree 作為 mysql 索引的資料結構,將來在讀取資料時,發生的磁碟 io 次數會更少,效能更優,因此最終 mysql 索引的資料結構使用的是 b+tree。
關於b-tree和b+tree可以參考以下文件
我們主要是分析mysql的innodb儲存引擎
我們來看下innodb的主鍵索引,普通索引和聯合索引的底層資料結構(圖是從某個大神那邊copy過來的,自己畫有點麻煩?)
主鍵索引
普通索引
聯合索引
我們來看幾個問題
為什麼innodb表必須有主鍵,並且推薦使用整型的自增主鍵?
為甚innodb表建議要有自增的主鍵,盡量建主鍵,建整形自增的?其實很簡單,設計如此,mysql設計的就是innodb把你的資料和主鍵索引用b+tree來組織的,沒有主鍵他的資料就沒有乙個結構來儲存。
建innodb表的時候沒有建主鍵,表也能建成功,為什麼?
不建主鍵不代表沒有主鍵,沒有建主鍵innodb會幫你選乙個字段,乙個可以標識唯一的字段,選為預設字段,如果這個字段唯一的話,不重複,可以建唯一索引的話,就會作為類似於唯一索引,用這個欄位來作為唯一索引來維護整個表的資料。如果沒有,mysql會生成乙個唯一的列,類似於rowid,只不過你看不到,他會用生成的這個唯一列,維護b+tree的結構,查資料的時候還是用b+tree的結構去查詢。
為什麼推薦整形呢?
我們想象一下查詢過程,是把節點load到記憶體然後在記憶體裡去比較大小,也就是在查詢的過程中要不斷的去進行資料的比對。假設uuid,既不自增也不是整形。問一下,是整形的1<2比較的效率高還是字串的「abc」和「abe」比較的效率高呢?顯然是前者,因為字串的比較是轉換成ascii碼一位一位的比,如果最後一位不一樣,比到最後才比較出大小,就比整形比較慢多了,儲存空間來說,整形更小。索引越節約資源越好。
為什麼是自增的呢?
我們可以看一下b-tree的葉子節點之間是沒有指標的,b+tree優化後增加了葉子節點之間的指標,如果我們遍歷資料,從當前節點遍歷完之後,就可以根據節點間的指標快速找到下乙個節點去遍歷。
這邊插乙個關於聯合索引的,聯合索引建立需要遵循最左匹配原則,他會先比對第乙個字段,比對完第乙個欄位才會比對第二個字段,最後才會比對第三個字段,舉個例子:
有這麼一條sql,a,b,c三個字段建立了乙個聯合索引
select * from table where a=*** and b=*** and c=***
那麼執行會跑3個索引,但是如果變成下面這條查詢語句的話就只會跑前面2個索引,而不會跑c索引了
select * from table where a=*** and b>*** and c=***
個人大致理解就是這樣,如果有寫的不對的,歡迎一起討論交流,謝謝!
Mysql索引底層原理分析
mysql索引底層原理分析,mysql索引的本質 mysql索引的底層原理 mysql索引的實戰經驗 面試問 資料庫中最常見的慢查詢優化方式是什麼?同學a 加索引。問 為什麼加索引能優化慢查詢?同學a 不知道同學b 因為索引其實就是一種優化查詢的資料結構,比如mysql中的索引是用b 樹實現的,而b...
mysql 索引底層原理分析
一 區分幾個概念 1 頁 1 頁號 記錄當前是第幾頁。2 頁目錄 記錄行資料,標記行開始的最小主鍵索引資料。3 行資料 標識每一行的資料。1 111a 標識第一行資料,1 表示主鍵索引。行與行資料使用鍊錶有序相連。2 b 樹 多個頁相互連線在一起,為了方便查詢會再向上生成乙個新的類似頁的東西,記錄頁...
Mysql 索引底層結構探索
索引用於提高資料庫表的資料訪問速度的一種資料結構,binary search trees red black trees b trees b trees,這些都可以用來做索引,為什麼mysql偏偏選擇b trees呢?下面我們就來分析一下原因 衡量乙個索引是否高效 io漸進複雜度 binary se...