MySQL之索引系列(一)

索引能夠提升數據查詢的效率,至關於一本書的目錄html

常見索引模型

數據庫的索引模型有不少種,其中比較常見、簡單的數據結構是哈希、有序數組和搜索樹數據庫

哈希表

哈希表是一種key-value結構的數據結構,key爲待查找的值,用一個hash函數計算key的哈希值,做爲存儲位置,value就放在這個位置,由於多個key可能計算出來hash值相同,即佔用相同的位置,因此value能夠是一個鏈表,裏面存着多個值。
數組


如圖,根據用戶id計算hash值,可能user二、user5兩個用戶計算出來的hash值相同,因此他們的數據以鏈表的形式存在於value。若是要獲取user6的信息,根據 hash( user6.id) 得出hash值爲3,則在3這個value中遍歷,獲取user6的信息。 一個好的hash函數計算獲得的值應該是很是分散的,不容易重複,這樣會減小遍歷的過程,增長查詢速度。
因爲hash存儲位置的值不是遞增的,而是散列的,所以插入數據時速度是很快的,可是若是要查找區間內的值 [user3,user9],只能挨個從user3開始遍歷查找,因此hash表這種結構適合於等值查詢的場景,不適合區間查詢

有序數組

有序數組對於上述區間查詢這一場景有優點,存儲狀態如圖:數據結構


按照id遞增存儲在數組中,若是須要查詢某個id對應的姓名,根據二分法時間複雜度爲O(log n),若是須要查詢一個區間的範圍,則開頭第一個user後一次日後查詢便可。可是若是須要大量插入數據,數據結構就不適合了,爲了保證id的順序性,須要往數組中間插入一條,則該id後面的數據一次向後移動,成本比較高。
以上可見,有序數組索引只適用於靜態存儲引擎,提供查詢、不插入的數據表

N叉樹

二叉樹的特色:每一個節點比左兒子大,比右兒子小。由結構可知時間複雜度爲O(log n),爲了維持這種結構,更新的時間複雜度一樣是O(log n)。除了二叉樹外還能夠有N叉樹,對於二叉樹來講,100萬節點的樹高20,也就是說查找一個數據頗有可能要訪問20個數據塊,這個速度就會很慢。因此這時候應該使用N叉樹,N取決於數據塊的大小。N叉樹因爲在讀寫上的性能優勢,以及適配磁盤的訪問模式,已經被普遍的應用在數據庫引擎中了函數

InnoDB的索引模型

innoDB使用了B+樹索引模型,每一個索引都對應着一棵B+樹。
索引類型分爲:主鍵索引和費主鍵索引
主鍵索引葉子節點存的是整行數據,也被稱爲聚簇索引;非主鍵索引的葉子節點內容是主鍵的值,也被稱爲二級索引。
也就是說若是經過主鍵id來查找,則只須要搜索id這棵B+樹
若是使用二級索引來查找,則先找到該二級索引對應的主鍵id而後再根據id索引樹在搜索一次,這個過程叫作回表
如圖:性能

select * from table where k = 3學習

以上SQL使用了二級索引K,首先搜索索引樹,獲得主鍵id的值爲300,再到主鍵索引樹找到300對應的數據,這一過程叫作回表 所以在應用中減量使用主鍵索,能夠減小回表過程cdn

索引維護

因爲B+樹的有序性,因此在插入新數據時須要調整,維持結構。 在自增主鍵的狀況下,主鍵系統本身動獲取主鍵id,按順序在最後插入一個葉子節點,是追加操做,不須要移動其餘的記錄。
使用業務邏輯字段作主鍵,則通常不能保證有序插入,寫數據的成本比較高
上文可知,非主鍵索引的葉子節點都是主鍵的值,若是主鍵長度越大,普通索引的葉子節點就越小,普通索引佔用的空間也就越小 從性能和存儲空間兩方面考慮,自增主鍵每每是更合理的選擇htm

本文爲極客時間《MySQL實戰45講》的學習筆記,其中含有部分原文,若有侵權行爲請聯繫我馬上刪除
第一節:一條SQL查詢語句的執行過程blog

相關文章
相關標籤/搜索