日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

MySQL 索引底层数据结构实现

發布時間:2025/3/12 数据库 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 MySQL 索引底层数据结构实现 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

  • 概述
  • 討論范圍
  • 查詢數據結構
    • 查詢數據結構種類及其高性能查詢原理
  • MySQL 索引的底層數據結構
    • MySQL 索引的需求分析
    • 選擇 MySQL 索引的底層數據結構
    • B- 樹和 B+ 樹的對比
    • MySQL 索引的底層數據結構揭秘

概述

MySQL 的索引是存儲引擎用于快速找到記錄的一種數據結構,是提升 SQL 執行效率的神器。
在正確建立及使用索引的情況下,查詢性能將會有非常大的提升(從 O(N) 提升到 O(logN),幾乎接近于常數級別);但在索引建立不正確或者使用不正確的情況下,將會進行全表掃描(O(N)),查詢性能就比較低下了。

討論范圍

為了不給讀者帶來可能的理解上的偏差以及困擾,在這里首先說明,本文中討論的索引是 MySQL 中 InnoDB 存儲引擎所使用的索引

查詢數據結構

為了方便大家理解 MySQL 索引的底層數據結構,以及索引為什么能夠提升查詢性能,首先從查詢數據結構開始講解。
查詢數據結構,光從字面上可能不太好理解。但是基于實際含義的角度上來看,或許應該叫便于查詢的數據結構,又或者叫高性能的查詢數據結構比較貼切。
即,查詢數據結構是一種能提升數據查詢效率的數據結構

查詢數據結構種類及其高性能查詢原理

常見的查詢數據結構,有以下幾種:

  • 有序數組:一個數組,數組中的元素已經全部有序。利用其有序的性質,使用二分查找可以獲得 O(logN) 時間復雜度的查詢效率
  • 跳表:一個鏈表(單或雙向都可以),鏈表中的所有節點都有序,且在原有鏈表的基礎上增加了一級或多級索引。利用其有序+索引性質,使用二分查找可以獲得 O(logN) 時間復雜度的查詢效率
  • 哈希表:一種維護了鍵和值的唯一映射關系的數據結構,其本質是將鍵通過哈希函數+解決哈希沖突的某種手段散列到數組中的一種方法。利用數組的隨機訪問能力,可以獲得在最好情況下 O(1) 查詢時間復雜度,最壞情況的時間復雜度取決于哈希函數與解決哈希沖突的方法有關。
  • 二叉搜索樹:一種節點間有序的二叉樹(具體定義在這里就不展開講了)。利用其有序的性質,使用二分查找在最好情況下可以獲得 O(logN) 時間復雜度的查詢效率,最壞情況下為 O(N)
  • 紅黑樹:一種自平衡的二叉搜索樹。利用其有序的性質,使用二分查找可以獲得 O(logN) 時間復雜度的查詢效率
  • B- 樹:B- 樹,是一種自平衡的多叉搜索樹。利用其有序的性質,使用二分查找可以獲得 O(logN) 時間復雜度的查詢效率
  • B+ 樹:B+ 樹,也是一種自平衡的多叉搜索樹。利用其有序的性質,使用二分查找可以獲得 O(logN) 時間復雜度的查詢效率

可以看出,上面的數據結構,除了哈希表外,其余的數據結構都是利用了有序這個性質,并結合二分查找方法,即可獲得較高的(O(N) 時間復雜度)查詢效率。
唯一一個例外是二叉搜索樹在最壞情況下(在節點分布極其不均勻,幾乎退化成單向鏈表的情況下),會退化成線性搜索,其復雜度為 O(N),如下圖所示:

可以看到,這個二叉搜索樹,幾乎已經退化成了一條單向鏈表,所以其查詢時間復雜度將會是 O(N)。
所以我們得出一個結論:想要提高查詢效率,最好利用一個數據有序,且能自平衡(或者不需要平衡操作)的數據結構,再結合二分查找方法,即可達到目標。
在上面這個,最重要的一點就是數據必須有序,因為如果數據無序,那么二分查找也無用武之地。

MySQL 索引的底層數據結構

假設你是 MySQL 的 InnoDB 存儲引擎的開發人員,你會選擇哪種數據結構作為索引底層的數據結構呢?

MySQL 索引的需求分析

想要實現一個功能,首先得分析清楚這個功能的需求是什么。現在我們想要實現 MySQL 的索引,那么索引的功能需求是什么呢?
總的來說 MySQL 的索引有以下幾個需求點:

  • 能夠大幅度提升查詢性能
  • 能支持范圍查詢
  • 易于維護,維護的時間復雜度應該盡可能地低
  • 從磁盤讀入內存的每個數據頁應該包含盡可能多的信息
  • 能盡可能地減少磁盤 IO 次數
  • 選擇 MySQL 索引的底層數據結構

    弄清楚需求后,我們使用排除法來篩選所有可用的查詢數據結構:

    • 有序數組:不能滿足 3、4、5,排除。有序數組隨機插入和刪除元素的復雜度為 O(N),且有序數組在數據量較大時,將數據從磁盤讀入內存的 IO 次數將不可控
    • 跳表:不能滿足 4、5,排除。跳表與有序數組相同,從磁盤讀入內存的每個數據頁取決于數據本身的大小;在數據量較大時,將數據從磁盤讀入內存的 IO 次數將不可控
    • 哈希表:不能滿足 2,排除。哈希表不支持范圍查詢
    • 二叉搜索樹:不能自平衡,排除
    • 紅黑樹:不能滿足 4、5,排除。紅黑樹雖然能自平衡,但是在數據量較大的情況下,樹的高度將會非常大,將數據從磁盤讀入內存的 IO 次數也會非常多
    • B- 樹:基本可以滿足所有條件
    • B+ 樹:可以滿足所有條件

    經過上面的比對,我們最終確定了 B- 樹和 B+ 樹兩種數據結構可以滿足我們的需求,那么這兩種數據結構哪種更適合用于實現 MySQL 的索引呢?

    B- 樹和 B+ 樹的對比

    B- 樹和 B+ 樹,兩者都屬于自平衡的多叉搜索樹。但是從細節上來說,兩者之間有如下的區別:

    • B+ 樹只有在葉子節點上才會攜帶數據,而 B- 樹在每個節點上都會攜帶數據
      • 這個特性決定了 B+ 樹在非葉子節點上存儲的關鍵字數量越多,那么樹的階就會越大,則樹中的節點就會越少,則樹的高度就會越低
      • 樹的高度越高,則每次查詢的時候需要進行的磁盤 IO 操作就會越多
      • 樹的階越大,即非葉子節點上存儲的關鍵字數量越多,則從磁盤讀入內存的每個數據頁所包含的信息數量就越多
    • B+ 樹對于范圍查詢的性能更高
      • B+ 樹的所有葉子節點組成了一個有序的鏈表,在進行范圍查詢時,只需要遍歷葉子節點組成的鏈表就行
      • B- 樹在進行范圍查找時,需要反復地中序遍歷,才能獲得范圍內的所有數據

    下面的圖說明了在存儲同一組數據時,B- 樹和 B+ 樹的區別:


    在這里,我們模擬 B- 樹因為所有節點都要存儲數據,所以階為 3 的情況;而 B+ 樹只有在葉子節點上才會存儲數據,所以階會比 B- 樹要大,這里設定為 4。
    可以看到,在存儲同一組數據時,B- 樹的高度比 B+ 樹要高;且 B+ 樹的所有葉子節點組成了一個有序鏈表,范圍查詢時更方便也更高效。

    MySQL 索引的底層數據結構揭秘

    根據上面的分析,我們可以得出,要實現 MySQL 索引,底層數據結構選擇 B+ 樹最為合適。而實際上,MySQL 的 InnoDB 存儲引擎也確實是使用 B+ 樹作為底層的數據結構的。
    而 InnoDB 除了實現標準的 B+ 樹功能外,還有以下的實現細節值得關注:

    • InnoDB 數據頁的大小(由參數 innodb_page_size 決定)決定了 B+ 樹的節點的大小,也決定了這個節點上存儲的關鍵字數量
      • 默認的一個頁的大小為 16KB,高度為 3 的 B+ 樹即可存儲千萬級別的數據量
    • 葉子節點組成的鏈表為雙向鏈表,可以更方便也是更高效地處理范圍查詢

    總結

    以上是生活随笔為你收集整理的MySQL 索引底层数据结构实现的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。