深入理解InnoDB(3)—索引的存儲結構

1. 索引的各種存儲結構及其優缺點

1.1 二叉樹

  1. 優點:
    二叉樹是一種比順序結構更加高效地查找目標元素的結構,它可以從第一個父節點開始跟目標元素值比較,如果相等則返回當前節點,如果目標元素值小于當前節點,則移動到左側子節點進行比較,大于的情況則移動到右側子節點進行比較,反復進行操作最終移動到目標元素節點位置。

  2. 缺點:

在大部分情況下,我們設計索引時都會在表中提供一個自增整形字段作為建立索引的列,在這種場景下使用二叉樹的結構會導致我們的索引總是添加到右側,在查找記錄時跟沒加索引的情況是一樣的

1.2 紅黑樹

  1. 優點:

紅黑樹也叫平衡二叉樹,它不僅繼承了二叉樹的優點,而且解決了上面二叉樹遇到的自增整形索引的問題,從下面的動態圖中可以看出紅黑樹會左旋、右旋對結構進行調整,始終保證左子節點數 < 父節點數 < 右子節點數的規則。

  1. 缺點:

在數據量大的時候,深度也很大。從圖中可以看出每個父節點只能存在兩個子節點,如果我們有很多數據,那么樹的深度依然會很大,可能就會超過十幾二十層以上,對我們的磁盤尋址不利,依然會花費很多時間查找。

1.3 Hash

  1. 優點:

對數據進行Hash(散列)運算,主流的Hash算法有MD5、SHA256等等,然后將哈希結果作為文件指針可以從索引文件中獲得數據的文件指針,再到數據文件中獲取到數據,按照這樣的設計,我們在查找where Col2 = 22的記錄時只需要對22做哈希運算得到該索引所對應那行數據的文件指針,從而在MySQL的數據文件中定位到目標記錄,查詢效率非常高。

  1. 缺點:

無法解決范圍查詢(Range)的場景,比如 select count(id) from sus_user where id >10;因此Hash這種索引結構只能針對字段名=目標值的場景使用。不適合模糊查詢(like)的場景。

1.4 B-Tree

既然紅黑樹存在缺點,那么我們可以在紅黑樹的基礎上構思一種新的儲存結構。解決的思路也很簡單,既然覺得樹的深度太長,就只需要適當地增加每個樹節點能存儲的數據個數即可,但是數據個數也必須要設定一個合理的閾值,不然一個節點數據個數過多會產生多余的消耗。

1.4.1 B-Tree的一些特點

  • 度(Degree)-節點的數據存儲個數,每個樹節點中數據個數大于 15/16*Degree(未驗證) 時會自動分裂,調整結構
  • 葉節點具有相同的深度,左子樹跟右子樹的深度一致
  • 葉節點的指針為空
  • 節點中的數據key從左到右遞增排列
  1. 優點:

BTree的結構可以彌補紅黑樹的缺點,解決數據量過大時整棵樹的深度過長的問題。相同數量的數據只需要更少的層,相同深度的樹可以存儲更多的數據,查找的效率自然會更高。

  1. 缺點:

從上面得知,在查詢單條數據是非常快的。但如果范圍查的話,BTree結構每次都要從根節點查詢一遍,效率會有所降低,因此在實際應用中采用的是另一種BTree的變種B+Tree(B+樹)。

2. B+Tree—InnoDB中的索引方案

2.1 相對于BTree,B+Tree做了哪些優化?

B+Tree存儲結構,只有葉子節點存儲數據
。新的B+樹結構沒有在所有的節點里存儲記錄數據,而是只在最下層的葉子節點存儲,上層的所有非葉子節點只存放索引信息,這樣的結構可以讓單個節點存放下更多索引值,增大度Degree的值,提高命中目標記錄的幾率。

這種結構會在上層非葉子節點存儲一部分冗余數據,但是這樣的缺點都是可以容忍的,因為冗余的都是索引數據,不會對內存造成大的負擔。這種結構會在上層非葉子節點存儲一部分冗余數據,但是這樣的缺點都是可以容忍的,因為冗余的都是索引數據,不會對內存造成大的負擔。

image.png
InnoDB中的索引是通過目錄項所指向的下一層頁號來一層一層去縮小搜索范圍,從而達到高效的查詢的。通過二分法對頁內的目錄項和目標值進行比對,查出下一層所在頁號,再在該頁下進行再次搜索,直到到達葉子節點

2.2 索引的存儲結構

索引中的目錄項其實長得跟我們的用戶記錄差不多,只不過目錄項中的兩個列是主鍵和頁號而已,所以InnoDB復用了之前存儲用戶記錄的數據頁來存儲目錄項,為了和用戶記錄做一下區分,我們把這些用來表示目錄項的記錄稱為目錄項記錄。

頁的組成結構也是一樣的(就是我們前邊介紹過的7個部分),都會為主鍵值生成Page Directory(頁目錄),從而在按照主鍵值進行查找時可以使用二分法來加快查詢速度。

image.png
不論是存放用戶記錄的數據頁,還是存放目錄項記錄的數據頁,我們都把它們存放到B+樹這個數據結構中了,所以我們也稱這些數據頁為節點。從圖中可以看出來,我們的實際用戶記錄其實都存放在B+樹的最底層的節點上,這些節點也被稱為葉子節點或葉節點,其余用來存放目錄項的節點稱為非葉子節點或者內節點,其中B+樹最上邊的那個節點也稱為根節點。

2.3 聚簇索引

我們上邊介紹的B+樹本身就是一個目錄,或者說本身就是一個索引。它有兩個特點:

使用記錄主鍵值的大小進行記錄和頁的排序,這包括三個方面的含義:

  1. 頁內的記錄是按照主鍵的大小順序排成一個單向鏈表。

  2. 各個存放用戶記錄的頁也是根據頁中用戶記錄的主鍵大小順序排成一個雙向鏈表。

  3. 存放目錄項記錄的頁分為不同的層次,在同一層次中的頁也是根據頁中目錄項記錄的主鍵大小順序排成一個雙向鏈表。

B+樹的葉子節點存儲的是完整的用戶記錄。

所謂完整的用戶記錄,就是指這個記錄中存儲了所有列的值(包括隱藏列)。

聚簇索引的優缺點

  • 可以把相關數據保存在一起。
  • 數據訪問更快。
  • 使用覆蓋索引掃描的查詢可以直接使用頁節點中的主鍵值。
  • 如果表在設計和查詢的時候能充分利用以上特點,將會極大提高性能。當然,聚簇索引也有它的缺點:
  • 聚簇索引最大限度提高了I/O密集型應用的性能,但如果所有的數據都存放在內存中,聚簇索引就沒有優勢了。
  • 插入速度嚴重依賴插入順序。這也是為什么InnoDB一般都會設置一個自增的int列作為主鍵。
  • 更新聚簇索引的代價很高,因為會強制InnoDB將每個被更新的行移到新的位置。
  • 如果不安順序插入新數據時,可能會導致"頁分裂"。
  • 二級索引可能會比想象的更大。因為在二級索引的頁子節點中包含了引用行的主鍵列。
  • 二級索引訪問可能會需要進行回表查詢。

2.4 二級索引

聚簇索引是根據主鍵比較大小的,而二級索引是通過用戶建立索引的字段來比較大小的。

并且B+樹的葉子節點存儲的并不是完整的用戶記錄,而只是c2列+主鍵這兩個列的值。目錄項記錄中不再是主鍵+頁號的搭配,而變成了c2列+頁號+主鍵的搭配。

并且如果需要查詢非索引字段的信息,需要拿著主鍵id回去聚簇索引中查找

2.5 聯合索引

在二級索引的基礎,采用多個字段進行比較,先根據最左邊的索引排一次序,如果存在相同的值,則根據次左邊的索引字段進行比較,如此類推。

3. InnoDB的B+樹索引的注意事項

B+樹的形成過程是這樣的

  • 每當為某個表創建一個B+樹索引(聚簇索引不是人為創建的,默認就有)的時候,都會為這個索引創建一個根節點頁面。最開始表中沒有數據的時候,每個B+樹索引對應的根節點中既沒有用戶記錄,也沒有目錄項記錄。

  • 隨后向表中插入用戶記錄時,先把用戶記錄存儲到這個根節點中。

  • 當根節點中的可用空間用完時繼續插入記錄,此時會將根節點中的所有記錄復制到一個新分配的頁,比如頁a中,然后對這個新頁進行頁分裂的操作,得到另一個新頁,比如頁b。這時新插入的記錄根據鍵值(也就是聚簇索引中的主鍵值,二級索引中對應的索引列的值)的大小就會被分配到頁a或者頁b中,而根節點便升級為存儲目錄項記錄的頁。

這個過程需要大家特別注意的是:一個B+樹索引的根節點自誕生之日起,便不會再移動。這樣只要我們對某個表建立一個索引,那么它的根節點的頁號便會被記錄到某個地方,然后凡是InnoDB存儲引擎需要用到這個索引的時候,都會從那個固定的地方取出根節點的頁號,從而來訪問這個索引。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/391439.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/391439.shtml
英文地址,請注明出處:http://en.pswp.cn/news/391439.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

有抱負/初級開發人員的良好習慣-避免使用的習慣

When youre learning to code, it can be easy to pick up some nasty habits along the way. Here are some tips to avoid common bad habits, and the good habits to keep in mind.當您學習編碼時&#xff0c;很容易在此過程中養成一些討厭的習慣。 這里有一些技巧&#xf…

業精于勤荒于嬉---Go的GORM查詢

查詢 //通過主鍵查詢第一條記錄 db.First(&user)SELECT * FROM users ORDER BY id LIMIT 1;// 隨機取一條記錄 db.Take(&user)SELECT * FROM users LIMIT 1;// 通過主鍵查詢最后一條記錄 db.Last(&user)SELECT * FROM users ORDER BY id DESC LIMIT 1;// 拿到所有的…

apache 虛擬主機詳細配置:http.conf配置詳解

Apache的配置文件http.conf參數含義詳解 Apache的配置由httpd.conf文件配置&#xff0c;因此下面的配置指令都是在httpd.conf文件中修改。主站點的配置(基本配置) (1) 基本配置:ServerRoot "/mnt/software/apache2" #你的apache軟件安裝的位置。其它指定的目錄如果沒…

深入理解InnoDB(4)—索引使用

1. 索引的代價 在了解索引的代價之前&#xff0c;需要再次回顧一下索引的數據結構B樹 如上圖&#xff0c;是一顆b樹&#xff0c;關于b樹的定義可以參見B樹&#xff0c;這里只說一些重點&#xff0c;淺藍色的塊我們稱之為一個磁盤塊&#xff0c;可以看到每個磁盤塊包含幾個數據…

[BZOJ1626][Usaco2007 Dec]Building Roads 修建道路

1626: [Usaco2007 Dec]Building Roads 修建道路 Time Limit: 5 Sec Memory Limit: 64 MB Submit: 1730 Solved: 727 [Submit][Status][Discuss]Description Farmer John最近得到了一些新的農場&#xff0c;他想新修一些道路使得他的所有農場可以經過原有的或是新修的道路互達…

雙城記s001_雙城記! (使用數據講故事)

雙城記s001Keywords: Data science, Machine learning, Python, Web scraping, Foursquare關鍵字&#xff1a;數據科學&#xff0c;機器學習&#xff0c;Python&#xff0c;Web抓取&#xff0c;Foursquare https://br.pinterest.com/pin/92816442292506979/https://br.pintere…

python:linux中升級python版本

https://www.cnblogs.com/gne-hwz/p/8586430.html 轉載于:https://www.cnblogs.com/gcgc/p/11446403.html

web前端面試總結

2019獨角獸企業重金招聘Python工程師標準>>> 摘要&#xff1a;前端的東西特別多&#xff0c;面試的時候我們如何從容應對&#xff0c;作為一個老兵&#xff0c;我在這里分享幾點我的經驗。 一、javascript 基礎(es5) 1、原型&#xff1a;這里可以談很多&#xff0c;…

783. 二叉搜索樹節點最小距離(dfs)

給你一個二叉搜索樹的根節點 root &#xff0c;返回 樹中任意兩不同節點值之間的最小差值 。 注意&#xff1a;本題與 530&#xff1a;https://leetcode-cn.com/problems/minimum-absolute-difference-in-bst/ 相同 示例 1&#xff1a; 輸入&#xff1a;root [4,2,6,1,3] 輸…

linux epoll機制對TCP 客戶端和服務端的監聽C代碼通用框架實現

1 TCP簡介 tcp是一種基于流的應用層協議&#xff0c;其“可靠的數據傳輸”實現的原理就是&#xff0c;“擁塞控制”的滑動窗口機制&#xff0c;該機制包含的算法主要有“慢啟動”&#xff0c;“擁塞避免”&#xff0c;“快速重傳”。 2 TCP socket建立和epoll監聽實現 數據結構…

linux中安裝robot環境

https://www.cnblogs.com/lgqboke/p/8252488.html&#xff08;文中驗證robotframework命令應該為 robot --version&#xff09; 可能遇到的問題&#xff1a; 1、python版本太低 解決&#xff1a;升級python https://www.cnblogs.com/huaxingtianxia/p/7986734.html 2、pip安裝報…

angular 模塊構建_我如何在Angular 4和Magento上構建人力資源門戶

angular 模塊構建Sometimes trying a new technology mashup works wonders. Both Magento 2 Angular 4 are very commonly talked about, and many consider them to be the future of the development industry. 有時嘗試新技術的mashup會產生奇跡。 Magento 2 Angular 4都…

tableau破解方法_使用Tableau瀏覽Netflix內容的簡單方法

tableau破解方法Are you struggling to perform EDA with R and Python?? Here is an easy way to do exploratory data analysis using Tableau.您是否正在努力使用R和Python執行EDA&#xff1f; 這是使用Tableau進行探索性數據分析的簡單方法。 Lets Dive in to know the …

六周第三次課

2019獨角獸企業重金招聘Python工程師標準>>> 六周第三次課 9.6/9.7 awk awk也是流式編輯器&#xff0c;針對文檔中的行來操作&#xff0c;一行一行地執行。 awk比sed更強大的功能是它支持了分段。 -F選項的作用是指定分隔符&#xff0c;如果不加-F選項&#xff0c;…

面試題字符集和編碼區別_您和理想工作之間的一件事-編碼面試!

面試題字符集和編碼區別A recruiter calls you for a position with your dream company. You get extremely excited and ask about their recruiting process. He replies saying “Its nothing big, you will have 5 coding rounds with our senior tech team, just the sta…

初探Golang(1)-變量

要學習golang&#xff0c;當然要先配置好相關環境啦。 1. Go 安裝包下載 https://studygolang.com/dl 在Windows下&#xff0c;直接下載msi文件&#xff0c;在安裝界面選擇安裝路徑&#xff0c;然后一直下一步就行了。 在cmd下輸入 go version即可看到go安裝成功 2. Golan…

macaca web(4)

米西米西滴&#xff0c;吃過中午飯來一篇&#xff0c;話說&#xff0c;上回書說道macaca 測試web&#xff08;3&#xff09;&#xff0c;參數驅動來搞&#xff0c;那么有小伙本又來給雷子來需求&#xff0c; 登錄模塊能不能給我給重新封裝一下嗎&#xff0c; 我說干嘛封裝&…

linux中安裝cx_Oracle

https://blog.csdn.net/w657395940/article/details/41144225 各種嘗試都&#xff0c;最后 pip install cx-Oracle 成功導入 轉載于:https://www.cnblogs.com/gcgc/p/11447583.html

rfm模型分析與客戶細分_如何使用基于RFM的細分來確定最佳客戶

rfm模型分析與客戶細分With some free time at hand in the midst of COVID-19 pandemic, I decided to do pro bono consulting work. I was helping a few e-commerce companies with analyzing their customer data. A common theme I encountered during this work was tha…

leetcode 208. 實現 Trie (前綴樹)

Trie&#xff08;發音類似 “try”&#xff09;或者說 前綴樹 是一種樹形數據結構&#xff0c;用于高效地存儲和檢索字符串數據集中的鍵。這一數據結構有相當多的應用情景&#xff0c;例如自動補完和拼寫檢查。 請你實現 Trie 類&#xff1a; Trie() 初始化前綴樹對象。 void…