MYSQL--浅析索引
索引是為了提高數據查詢的效率,類似于書的目錄。
索引的常見模型有三種:
1.哈希表:
只適用于等值查詢,不適用于范圍查詢
為什么呢?
哈希表是(key,value)的格式存儲,存儲的數據不一定是按照順序存的
比如user,有id,name,address三個屬性,用id%5作為哈希函數
現在存入3,2,1,4,7幾個id,如果我們要找id=2的user,2%5=2,很容易發現他在哈希表的第二個位置,但是id>2的不一定就存在第二個位置以后,比如id=6,6%5=1
那么如果位置沖突怎么辦?
上面已經存入了id=2的user,現在要存入id=7的user,7%5=2,也要存在第二個位置
使用拉鏈法解決
2.有序數組:
更新慢,查詢快,查詢的時間復雜度是log(n)
但是如果更新,必須要移動更新位置之后的元素
所以有序數組適用于靜態的數據庫,或者更新很少的數據庫。
比如2015年的人口信息,數據不會再改變
3.二叉搜索樹:
更新,查詢的時間復雜度都是log(n)
一般不推薦使用二叉樹
比如一棵 100 萬節點的平衡二叉樹,樹高 20。一次查詢可能需要訪問 20 個數據塊。在機械硬盤時代,從磁盤隨機讀一個數據塊需要 10 ms 左右的尋址時間。也就是說,對于一個 100 萬行的表,如果使用二叉樹來存儲,單獨訪問一個行可能需要 20 個 10 ms 的時間,這個查詢可真夠慢的。為了讓一個查詢盡量少地讀磁盤,就必須讓查詢過程訪問盡量少的數據塊。那么,我們就不應該使用二叉樹,而是要使用“N 叉”樹。這里,“N 叉”樹中的“N”取決于數據塊的大小。以 InnoDB 的一個整數字段索引為例,這個 N 差不多是 1200。這棵樹高是 4 的時候,就可以存 1200 的 3 次方個值,這已經 17 億了。考慮到樹根的數據塊總是在內存中的,一個 10 億行的表上一個整數字段的索引,查找一個值最多只需要訪問 3 次磁盤。其實,樹的第二層也有很大概率在內存中,那么訪問磁盤的平均次數就更少了。
N叉樹中右邊的兄弟比左邊的兄弟值大
InnoDB的索引模型:
每一個索引在 InnoDB 里面對應一棵 B+ 樹。
索引類型分為主鍵索引和非主鍵索引。主鍵索引的葉子節點存的是整行數據。在 InnoDB 里,主鍵索引也被稱為聚簇索(clustered index)。非主鍵索引的葉子節點內容是主鍵的值。在 InnoDB 里,非主鍵索引也被稱為二級索引(secondary index)。
主鍵索引和普通索引有什么區別:
主鍵索引:select *?from user where id = 10,只用搜索id這顆二叉樹
普通索引:select * from user where name='張三',先搜索name這顆二叉樹中名字是張三的,再通過name這棵樹獲取到張三的id,去搜id這顆二叉樹,再獲取到全部信息。
去搜id這顆二叉樹的操作叫做回寫
索引維護:b+樹的合并,拆裂
索引什么時候使用自增主鍵,什么時候用自己的屬性?
自增主鍵的插入數據模式,正符合了我們前面提到的遞增插入的場景。每次插入一條新記錄,都是追加操作,都不涉及到挪動其他記錄,也不會觸發葉子節點的分裂。而有業務邏輯的字段做主鍵,則往往不容易保證有序插入,這樣寫數據成本相對較高。
?
主鍵長度越小,普通索引的葉子節點就越小,普通索引占用的空間也就越小。所以,從性能和存儲空間方面考量,自增主鍵往往是更合理的選擇。
有沒有什么場景適合用業務字段直接做主鍵的呢?還是有的。比如,有些業務的場景需求是這樣的:只有一個索引;該索引必須是唯一索引。這就是典型的 KV 場景。由于沒有其他索引,所以也就不用考慮其他索引的葉子節點大小的問題。這時候我們就要優先考慮上一段提到的“盡量使用主鍵查詢”原則,直接將這個索引設置為主鍵,可以避免每次查詢需要搜索兩棵樹。
?
回到主鍵索引樹搜索的過程,我們稱為回表。
那么有沒有什么方法可以避免回表呢??
1.覆蓋索引:
select id from user where name='張三'
這種的我們可以發現,只需要查找user,那么通過找name這顆二叉樹獲得id就行,不用回寫。
類似上面的過程就叫做覆蓋索引
2.最左前綴:聯合索引的最左 N 個字段,也可以是字符串索引的最左 M 個字符
3.聯合索引:根據創建聯合索引的順序,以最左原則進行where檢索,比如(age,name)以age=1 或 age= 1 and name=‘張三’可以使用索引,單以name=‘張三’ 不會使用索引,考慮到存儲空間的問題,還請根據業務需求,將查找頻繁的數據進行靠左創建索引。
4.索引下推:like 'hello%’and age >10 檢索,MySQL5.6版本之前,會對匹配的數據進行回表查詢。5.6版本后,會先過濾掉age<10的數據,再進行回表查詢,減少回表率,提升檢索速度
總結
以上是生活随笔為你收集整理的MYSQL--浅析索引的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Leetcode--80. 删除排序数组
- 下一篇: 【剑指offer】面试题32 - III