MySql資料庫索引底層資料結構

2021-10-02 20:14:58 字數 3357 閱讀 8610

索引是幫助資料庫高效獲取資料的排好序資料結構

常見的資料結構有:hash、二叉樹、紅黑樹、b樹、b+樹。

首先來看如果採用hash,它是把資料進行hash直接對應磁碟儲存引用位址,這樣查詢資料直接告訴磁碟資料在哪,查詢很快。但是 hash 還是有些不足:那就是不能範圍查詢,如果通過大於或者小於去篩選資料,就需要掃瞄整個hash表,效率大大降低了。當然mysql還是提供了hash索引,畢竟有些場合還是用起來也不錯。

採用二叉樹,每個節點儲存了索引對應欄位的值,這樣我們根據索引去查詢時就可以避免全表掃瞄,時間複雜度降為o(log n)。看起來很美好,但是二叉樹在值單邊遞增的情況下回退化到鍊錶。

採用紅黑樹,又叫自平衡二叉樹,會通過特定操作保持二叉查詢樹的平衡,避免了單邊增長的問題,從而獲得較高的查詢效能。

從上面我們發現,紅黑樹相比較於二叉樹又進步了一些,但紅黑樹還是有些問題:那就是資料量大的話,紅黑樹的深度會很深,也就是說深度不可控,這樣一來查詢資料還是會很耗時。100w資料時樹的高度大概在20左右,那也就是說從有著100w條資料的平衡二叉樹中找乙個資料,最壞的情況下需要20次磁碟的io查詢。是不是可以每個節點多增加一些資料呢?

b樹的結構為:

動態演示資料結構的**

b樹的特點:

1.葉子節點具有相同的深度,葉子節點的指標為空

2.所有索引元素不可重複

3.節點中資料索引是有序的,即從左到右遞增

實際上mysql使用的是b+樹

b+樹是在b樹基礎上的一種優化,使其更適合實現儲存索引結構。b+樹與b樹的結構很像,但是也有幾個自己的特性:

1、所有的非葉子節點只儲存索引資訊,因此可以放更多的索引

2、葉子結點中包含了全部索引資訊。

3、所有葉子節點之間都有乙個鏈指標,來提高區間訪問的效能

為什麼要做這樣的改進呢?我們還需要了解的乙個知識點是作業系統從磁碟讀取資料到記憶體是以磁碟塊(block)為基本單位的,位於同乙個磁碟塊中的資料會被一次性讀取出來。即使只需要乙個位元組,磁碟也會從這個位置開始,順序向後讀取一定長度的資料放入記憶體。這樣做的理論依據是電腦科學中著名的區域性性原理:當乙個資料被用到時,其附近的資料也通常會馬上被使用。

預讀的長度一般為頁(page)的整數倍,innodb預讀大小預設為16k。頁是計算機管理儲存器的邏輯塊,作業系統往往將磁碟儲存區分割為連續的大小相等的塊,每個儲存塊稱為一頁,在許多作業系統中頁的大小通常為4k。

b+樹相比b樹有哪些優勢呢?

1.由於b+樹所有的索引都在葉子結點,並且結點之間有指標連線,在找大於某個關鍵字或者小於某個關鍵字的資料的時候,b+樹只需要找到該關鍵字然後沿著鍊錶遍歷就可以了,而b樹還需要遍歷該關鍵字結點的根結點去搜尋。

2.由於b樹的每個結點(這裡的結點可以理解為乙個資料頁)都儲存索引+實際資料,而b+樹非葉子結點只儲存索引資訊。而每個節點也就是每個頁的大小是有限的,所以b樹同一頁能儲存的資料會比b+樹儲存的更少。這樣同樣總量的資料,b樹的深度會更大,增大查詢時的磁碟i/o次數,進而影響查詢效率。

總的來說b+樹即減少了查詢次數也提高了很好的範圍查詢效能。

每個表可以使用不同的儲存引擎。開發中使用最多的是innodb儲存引擎。

索引屬於儲存引擎級別的概念,不同儲存引擎對索引的實現方式是不同的。下面主要討論myisam和innodb兩個儲存引擎的索引實現方式。

myisam引擎使用b+tree作為索引結構,葉節點的data域存放的是資料記錄的儲存位址。對應硬碟檔案裡每個表都有(.myd data)資料 + (.myi index)索引 + (.frm frame)結構三個檔案。

下圖是myisam索引的原理圖:

這裡設表一共有三列,假設我們以col1為主鍵,則下圖是乙個myisam表的主索引(primary key)示意。可以看出myisam的索引檔案僅僅儲存資料記錄的位址。

在myisam中,主索引和輔助索引(secondary key)在結構上沒有任何區別,只是主索引要求key是唯一的,而輔助索引的key可以重複。如果我們在col2上建立乙個輔助索引,則此索引的結構如下圖所示:

同樣也是一棵b+樹,data域儲存資料記錄的位址。因此myisam中索引檢索的演算法為首先按照b+樹搜尋演算法搜尋索引(索引還會快取進記憶體),如果指定的key存在,則取出其data域中儲存的儲存位址,去磁碟讀取相應的資料記錄(稱為回表)。

innodb的資料檔案本身就是按b+樹組織的乙個索引結構檔案。myisam索引檔案和資料檔案是分離的,索引檔案僅儲存資料記錄的位址。而在innodb中,表資料檔案本身就是按b+tree組織的乙個索引結構,這棵樹的葉節點data域儲存了完整的資料記錄,這個索引的key是資料表的主鍵。

上圖是innodb主索引(同時也是表資料檔案)的示意圖,可以看到葉子節點包含了完整的資料記錄。這種索引叫做聚集索引。

第二個與myisam索引的不同是innodb的輔助索引data域儲存相應記錄主鍵的值。下圖為定義在col3上的乙個輔助索引:

輔助索引的data儲存主鍵的節點不僅可以節省記憶體空間,而且利於保證資料的一致性,修改值只要修改主索引檔案就行了。

聚集索引這種實現方式使得如果按主鍵的搜尋不需要回表操作比myisam高效很多,但是輔助索引搜尋需要檢索兩遍索引:首先檢索輔助索引獲得主鍵,然後用主鍵到主索引中檢索獲得記錄。

了解不同儲存引擎的索引實現方式對於正確使用和優化索引都非常有幫助,例如知道了innodb的索引實現後,就很容易明白:

開發中一般推薦使用聯合索引,因此很多索引的建立原則都和聯合索引有著重要關係

下面是聯合索引的底層儲存結構

Mysql索引底層資料結構

想要了解索引,首先要知道索引到底是什麼呢 索引是幫助mysql高效獲取資料的排好序的資料結構 通俗來講就好比喻一本書,那這本書的目錄就好比做索引 索引儲存在檔案裡 儲存引擎是myisam的索引檔案儲存在 myi檔案中,儲存引擎是innodb的索引檔案儲存在 idb檔案中 通常資料庫中的資料就是存在硬...

mysql 索引 層數 mysql 索引底層

hash索引o 1 b 樹索引 o logn 為什麼紅黑樹出現了,因為防止某些情況下二叉排序樹退化為鍊錶 誕生了二叉排序平衡樹 樹的效能取決於樹的高度 為什麼db要用m路b樹,為了再降低樹的高度,減少db 磁碟io 次數,如果在記憶體中,紅黑樹效率更高 為什麼m不能無限大,因為會退化成有序陣列,無法...

MySQL資料庫索引底層原理

綜述 mysql索引底層採用的是b樹和b 樹來實現。那為什麼是b樹和b 樹而不是其他諸如陣列 鍊錶 平衡二叉樹這些資料結構呢?下面來學習。1 資料庫檔案儲存方式 資料庫檔案都是以磁碟檔案儲存在系統中的,這也是資料庫能夠持久化儲存資料的原因。2 從資料庫讀取資料的原理 從資料庫中讀取資料,先不考慮從快...