1. 程式人生 > >B+樹與資料庫索引

B+樹與資料庫索引

本文對兩篇文章進行了提取總結: 一、innodb儲存引擎索引概述: innodb儲存引擎支援兩種常見的索引:B+樹索引和雜湊索引。 innodb支援雜湊索引是自適應的,innodb會根據表的使用情況自動生成雜湊索引。 B+樹索引就是傳統意義上的索引,是關係型資料庫中最常用最有效的索引。B+樹是從最早的平衡二叉樹演變而來,但是B+樹不是一個二叉樹。B+中的B不代表二叉(Binary),而是代表平衡(Balance)。

注意:B+樹索引並不能找到一個鍵值對應的具體行。b+樹索引只能查到被查詢資料行所在的頁,然後資料庫通過把頁讀入記憶體,再在記憶體中查詢,最後得到結果。

索引型別:

根據資料庫的功能,可以在資料庫設計器中建立索引:唯一索引、主鍵索引和聚集索引。 儘管唯一索引有助於定位資訊,但為獲得最佳效能結果,建議改用主鍵或唯一約束。  

唯一索引: UNIQUE 例如:create unique index stusno on student(sno);

表明此索引的每一個索引值只對應唯一的資料記錄,對於單列惟一性索引,這保證單列不包含重複的值。對於多列惟一性索引,保證多個值的組合不重複。

主鍵索引: primary key

資料庫表經常有一列或列組合,其值唯一標識表中的每一行。該列稱為表的主鍵。 在資料庫關係圖中為表定義主鍵將自動建立主鍵索引,主鍵索引是唯一索引的特定型別。該索引要求主鍵中的每個值都唯一。當在查詢中使用主鍵索引時,它還允許對資料的快速訪問。 

聚集索引(也叫聚簇索引):cluster 

在聚集索引中,表中行的物理順序與鍵值的邏輯(索引)順序相同。一個表只能包含一個聚集索引。 如果某索引不是聚集索引,則表中行的物理順序與鍵值的邏輯順序不匹配。與非聚集索引相比,聚集索引通常提供更快的資料訪問速度。

二、B+樹索引介紹 B+樹索引的本質是B+樹在資料庫中的實現。但是B+樹索引有一個特點是高扇出性,因此在資料庫中,B+樹的高度一般在2到3層。也就是說查詢某一鍵值的記錄,最多隻需要2到3次IO開銷。按磁碟每秒100次IO來計算,查詢時間只需0.0.2到0.03秒。 資料庫中B+樹索引分為聚集索引(clustered index)和非聚集索引(secondary index).這兩種索引的共同點是內部都是B+樹,高度都是平衡的,葉節點存放著所有資料。不同點是葉節點是否存放著一整行資料。 (1) 聚集索引 Innodb儲存引擎表是索引組織表,即表中資料按主鍵順序存放。而聚集索引就是按每張表的主鍵構造一顆B+樹。並且葉節點存放整張表的行記錄資料。每張表只能有一個聚集索引(一個主鍵)。 聚集索引的另一個好處是它對於主鍵的排序查詢和範圍的速度非常快。葉節點的資料就是我們要找的資料。 在B+Tree的每個葉子節點增加一個指向相鄰葉子節點的指標,就形成了帶有順序訪問指標的B+Tree。做這個優化的目的是為了提高區間訪問的效能,例如如果要查詢key為從18到49的所有資料記錄,當找到18後,只需順著節點和指標順序遍歷就可以一次性訪問到所有資料節點,極大提到了區間查詢效率。

主鍵排序查詢:例如我們要找出最新的10條團購訂單,由於B+樹是雙項鍊表,我們可以迅速找到最後一個頁,並取出10條記錄。
主鍵範圍查詢:如果要通過主鍵查詢某一範圍內的資料,通過葉節點的上層中間節點就能得到頁的範圍,之後直接讀取資料頁即可。
(2) 輔助索引 輔助索引(也稱非聚集索引)。葉級別不包含行的全部資料,葉級別除了包含行的鍵值以外,每個索引行還包含了一個書籤(bookmark),該書籤告訴innodb儲存引擎,哪裡可以找到與索引對應的資料。 輔助索引的存在並不影響資料再聚集索引中的組織,因此一個表可以有多個輔助索引。當通過輔助索引查詢資料時,innodb會遍歷輔助索引並通過葉級別的指標獲得指向主鍵索引的主鍵。然後再通過主鍵索引找到一行完整的資料。 三、B+樹索引的使用 (1).什麼時候使用B+索引 當查詢表中很少一部分資料時,B+索引才有意義。對於性別,地區型別欄位,他們取值範圍很小,即低選擇性。這時加B+索引是沒有必要的。相反,某個欄位取值範圍很廣,如姓名,幾乎沒有重複,即高選擇性,則使用B+索引是比較合適的。因此。當訪問高選擇性欄位並取出很少一部分資料時,該欄位加B+索引是非常有效的。但是當取出的資料行佔表中大部分資料時,資料庫就不會使用B+索引了。
(2)順序讀、隨機讀         順序讀是指順序的讀取磁碟上的塊,隨機讀是指訪問的塊是不連續的,需要磁碟的磁頭不斷移動。隨機讀的效能是遠遠低於順序讀的。        在資料庫中,順序讀根據索引的葉節點就能順序的讀取所需的行資料,這個順序讀只是邏輯的順序讀,在磁碟上可能還是隨機讀。隨機讀是指訪問輔助索引葉節點不能完全得到結果,需要根據輔助索引頁節點中的主鍵去尋找實際資料行。對於一些取表裡很大部分資料的查詢,正式因為讀取是隨機讀,而隨機讀的效能會遠低於順序讀。所以優化器才會選擇全部掃描順序讀,而不使用索引。
四、雜湊索引

雜湊索引的示意圖則是這樣的:

(圖片源自網路)

簡單地說,雜湊索引就是採用一定的雜湊演算法,把鍵值換算成新的雜湊值,檢索時不需要類似B+樹那樣從根節點到葉子節點逐級查詢,只需一次雜湊演算法即可立刻定位到相應的位置,速度非常快。

從上面的圖來看,B+樹索引和雜湊索引的明顯區別是:

  • 如果是等值查詢,那麼雜湊索引明顯有絕對優勢,因為只需要經過一次演算法即可找到相應的鍵值;當然了,這個前提是,鍵值都是唯一的。如果鍵值不是唯一的,就需要先找到該鍵所在位置,然後再根據連結串列往後掃描,直到找到相應的資料;

  • 從示意圖中也能看到,如果是範圍查詢檢索,這時候雜湊索引就毫無用武之地了,因為原先是有序的鍵值,經過雜湊演算法後,有可能變成不連續的了,就沒辦法再利用索引完成範圍查詢檢索;

  • 同理,雜湊索引也沒辦法利用索引完成排序,以及like ‘xxx%’ 這樣的部分模糊查詢(這種部分模糊查詢,其實本質上也是範圍查詢);

  • 雜湊索引也不支援多列聯合索引的最左匹配規則

  • B+樹索引的關鍵字檢索效率比較平均,不像B樹那樣波動幅度大,在有大量重複鍵值情況下,雜湊索引的效率也是極低的,因為存在所謂的雜湊碰撞問題

通過觀察搜素模式,mysql會利用index key的字首建立雜湊索引,這個字首可以是任意長度,並且它可能僅僅是B-tree上的某些值,而不是整個b-tree。雜湊索引通過檢測,會在經常被訪問的index pages上建立雜湊索引。