1. 程式人生 > 其它 >【Java】【資料庫】索引為何使查詢變得更快?--B+樹

【Java】【資料庫】索引為何使查詢變得更快?--B+樹

排序資料的二分查詢

二分查詢的時間複雜度是\(O(log_2n)\),明顯快於暴力搜尋。

索引

建立索引的資料,就是通過事先排好順序,在查詢時可以應用二分查詢來提高查詢效率。

所以索引應該儘可能建立在主鍵這樣的欄位上,因為主鍵必須唯一,所以這樣生成的二叉查詢樹的效率是最高的。

資料庫索引的原理-- B+ 樹

資料庫用 B+ 樹來實現索引


其中, 非葉子節點形如

\(<P_1,K_1,P_2,K_2,...,P_{c-1},K_{c-1},P_c>\)

以第一層為例,\(<P_1,59,P_2,97,P_3>\).滿足資料部分(\(K_i\))從小到大有序排列,且指標\(P_i\)

指向的下一個節點\(X\)滿足\(K_{i-1}<X<=K_i\) , 例如圖中的樹,59在它左邊節點指向的樹裡,44在它左邊結點指向的樹裡,15在它左邊結點指向的樹裡,且都是在最右邊的位置

B+樹延伸

查詢操作

以上圖查詢\(key=59\)為例,
先訪問根節點\([59,97]\), 發現\(key\)小於等於根節點中的第一個數\(59\), 於是繼續訪問\(59\)左邊的指標指向的節點\([15,44,59]\), 發現\(key\)小於等於第三個樹\(59\), 於是訪問\(59\)左邊的指標指向的葉子節點\([51,59]\), 遍歷找到要查詢的元素\(59\).

葉子節點的詳細結構如下圖

由於資料指標只在葉子節點上,所以 B+ 樹所有查詢所有關鍵字的磁碟 \(I/O\) 的次數都是樹的高度。

區間查詢

在上面的葉子節點圖中,我們可以看到每個葉子節點有一個指標\(P_{next}\), 它的作用體現在區間查詢的時候。

例如,需要查詢\([21,63]\)之間的關鍵字。

  1. \(21<59\),訪問\(59\)左邊指標指向的節點\([15,44,59]\).
  2. \(15<21<44\), 訪問\(44\)左邊指標指向的葉子節點\([21,37,44]\).
  3. 遍歷這個葉子節點找到\(21\),下面的操作就如同單鏈表的遍歷,一直遍歷到\(63\)即可.

插入操作

不細說了,這篇文章的動圖能說明一切

知乎文章
只把動圖貼到這裡
沒有超出葉子結點的最大容量m

超出m,要分裂葉子節點

分裂葉子節點導致上層的節點也超出m,要分裂上層的節點

插入數值比當前最大值還大,要保證新的最大值在根節點中,需要重新調整 B+ 樹

B+ 樹的複雜度

查詢、插入和刪除等操作的時間複雜度都是\(O(logn)\)
至於這個結論怎麼得出的,還是看那篇知乎文章吧,寫得太好了。