綜述:
mysql索引底層採用的是b樹和b+樹來實現。那為什麼是b樹和b+樹而不是其他諸如陣列、鍊錶、平衡二叉樹這些資料結構呢?下面來學習。
1、資料庫檔案儲存方式
資料庫檔案都是以磁碟檔案儲存在系統中的,這也是資料庫能夠持久化儲存資料的原因。
2、從資料庫讀取資料的原理
從資料庫中讀取資料,先不考慮從快取中讀取的情況,那就是直接從磁碟檔案中讀取資料,我們都知道,從磁碟檔案中讀取資料是十分耗時的,資料庫select的時間取決於執行磁碟io的次數,所以減少磁碟io就可以顯著提高讀取資料的速度。
3、減少磁碟io操作的影響因素
磁碟io與預讀:
磁碟讀取分為分為尋道時間、旋轉延遲、傳輸時間三個部分,這三個部分耗時相加就是一次磁碟io的時間,這個成本是訪問記憶體的十萬倍左右;正是由於磁碟io是非常昂貴的操作,所以計算機作業系統對此做了優化:預讀;每一次io時,不僅僅把當前磁碟位址的資料載入到記憶體,同時也把相鄰資料也載入到記憶體緩衝區中。因為區域性預讀原理說明:當訪問乙個位址資料的時候,與其相鄰的資料很快也會被訪問到。每次磁碟io讀取的資料我們稱之為一頁(page)。一頁的大小與作業系統有關,一般為4k或者8k。這也就意味著讀取一頁內資料的時候,實際上發生了一次磁碟io。
正因為有了磁碟io預讀機制,所以才有了減少磁碟io的可能,因為一次磁碟io操作,可以查詢到物理儲存中相鄰的一大片資料。
一次磁碟io操作可以取出物理儲存中相鄰的一大片資料,如果查詢的索引資料(就是b+樹中從根節點一直到葉子節點整個過程中查詢的節點數)都集中在該區域,那麼只需要一次磁碟io,否則就需要多次磁碟io。
4、資料庫中使用什麼資料結構作為索引
①、鍊錶,鍊錶的查詢速度是o(n),每次查詢都得從煉表頭開始查詢,如果有資料10000條,目標資料在第5000行,則每次都會從頭開始遍歷5000次才讀取到。
②、陣列,陣列的查詢速度是o(1),查詢速度確實很快,但是對於陣列來說insert、update、delete等就顯得很乏力了;而且另乙個不使用陣列的原因是索引是儲存在磁碟中的,當索引非常大的時候無法一次載入到記憶體中。
③、平衡二叉樹,二叉查詢樹查詢的時間複雜度是o(logn),查詢速度最快和比較次數最少,既然效能已經如此優秀,但為什麼實現索引是使用b-tree而不是二叉查詢樹,關鍵因素是磁碟io的次數。
④、b樹和b+樹,資料庫索引採用的資料結構。
b樹和b+樹閱讀:btree和b+tree詳解
5、為什麼資料庫選b-tree或b+tree而不是二叉樹作為索引結構
閱讀:為什麼資料庫選b-tree或b+tree而不是二叉樹作為索引結構
推薦閱讀:深入理解資料庫索引採用b樹和b+樹的原因
6、聚簇索引與非聚簇索引
mysql中最常見的兩種儲存引擎分別是myisam和innodb,分別實現了非聚簇索引和聚簇索引。
聚簇索引的解釋是:聚簇索引的順序就是資料的物理儲存順序;
非聚簇索引的解釋是:索引順序與資料物理排列順序無關。
在索引的分類中,我們可以按照索引的鍵是否為主鍵來分為「主索引」和「輔助索引」,使用主鍵鍵值建立的索引稱為「主索引」,其它的稱為「輔助索引」。因此主索引只能有乙個,輔助索引可以有很多個。
myisam——非聚簇索引
innodb——聚簇索引
使用主索引的時候,更適合使用聚簇索引,因為聚簇索引只需要查詢一次,而非聚簇索引在查到資料的位址後,還要進行一次i/o查詢資料。
因為聚簇輔助索引儲存的是主鍵的鍵值,因此可以在資料行移動或者頁**的時候降低成本,因為這時不用維護輔助索引。但是由於主索引儲存的是資料本身,因此聚簇索引會占用更多的空間。
聚簇索引在插入新資料的時候比非聚簇索引慢很多,因為插入新資料時需要檢測主鍵是否重複,這需要遍歷主索引的所有葉節點,而非聚簇索引的葉節點儲存的是資料位址,占用空間少,因此分布集中,查詢的時候i/o更少,但聚簇索引的主索引中儲存的是資料本身,資料占用空間大,分布範圍更大,可能占用好多的扇區,因此需要更多次i/o才能遍歷完畢。
下圖可以形象的說明聚簇索引和非聚簇索引的區別
從上圖中可以看到聚簇索引的輔助索引的葉子節點的data儲存的是主鍵的值,主索引的葉子節點的data儲存的是資料本身,也就是說資料和索引儲存在一起,並且索引查詢到的地方就是資料(data)本身,那麼索引的順序和資料本身的順序就是相同的;
而非聚簇索引的主索引和輔助索引的葉子節點的data都是儲存的資料的實體地址,也就是說索引和資料並不是儲存在一起的,資料的順序和索引的順序並沒有任何關係,也就是索引順序與資料物理排列順序無關。
參考文章:深入理解mysql索引原理和實現——為什麼索引可以加速查詢?
關於索引的基礎知識:mysql基礎知識之索引
資料庫 索引的底層原理
索引的底層原理 mysql支援兩種索引,b 樹索引,雜湊表索引 儲存引擎為myisam和innodb的索引結構 myisam儲存引擎 主鍵索引 非聚集索引 myisam引擎使用b 樹作為索引結構 葉節點的data域存放的是資料記錄位址 myisam中,主索引和輔助索引在結構上沒有任何區別,只是主索引...
MySQL索引底層(二) 索引底層原理
聚集索引 上次我們講到了主鍵的索引,我們可以執行一下sql語句 explain select from t user where a 1 我們可以看到這條sql走的是主鍵的索引,而在mysql的innodb中,主鍵索引則是聚集索引,資料的物理順序與鍵值的邏輯 索引 順序相同,其實就是說主鍵索引跟其他...
MySQL索引底層原理
通過hash演算法,能快速檢索資料 資料碰撞問題用鏈位址法 無法進行範圍搜尋 解決雜湊索引無法範圍搜尋的問題 極端情況下會退化成線性鍊錶,自增主鍵必然會導致極端情況 會自動調整樹形態,使其保持平衡,調整會消耗效能 無法完全解決二叉查詢樹的問題 絕對平衡的二叉樹,更耗效能 根本解決了紅黑數的問題 由於...