深入浅出MySql索引
索引的作用
提高數據查詢效率
索引的常見模型
可以用于提高讀寫效率的數據結構很多,這里三種常見、也比較簡單的數據結構,它們分別是哈希表、有序數組和搜索樹
哈希表
鍵 - 值(key - value) 的形式,哈希思路:把值放在數組里,用一個哈希函數把key換算成一個確定的位置,然后把value放在數組的這個位置。
哈希沖突的處理辦法:鏈表
哈希表適用場景: 只有等值查詢的場景,比如 Memcached 及其他一些 NoSQL 引擎。
有序數組
按順序存儲。查詢用二分法就可以快速查詢,時間復雜度是:O(log(N))
有序數組在等值查詢和范圍查詢場景中的性能就都非常優秀。
場景:有序數組索引只適用于靜態存儲引擎,
二叉搜索樹
二叉搜索樹的特點是:父節點左子樹所有結點的值小于父節點的值,右子樹所有結點的值大于父節點的值。這樣如果你要查 ID_card_n2 的話,按照圖中的搜索順序就是按照 UserA -> UserC -> UserF -> User2 這個路徑得到。這個時間復雜度是 O(log(N))。為了維持 O(log(N)) 的查詢復雜度,你就需要保持這棵樹是平衡二叉樹。為了做這個保證,更新的時間復雜度也是 O(log(N))。
樹可以有二叉,也可以有多叉。多叉樹就是每個節點有多個兒子,兒子之間的大小保證從左到右遞增。二叉樹是搜索效率最高的,但是實際上大多數的數據庫存儲卻并不使用二叉樹。其原因是,索引不止存在內存中,還要寫到磁盤上。
InnoDB 的索引模型
每一個索引在 InnoDB 里面對應一棵 B+ 樹,即一個主鍵索引樹和多個非主鍵索引樹。
執行查詢的效率,使用主鍵索引 > 使用非主鍵索引 > 不使用索引。
如果不使用索引進行查詢,則從主索引 B+ 樹的葉子節點進行遍歷。
主鍵索引和普通索引的查詢有什么區別?
非主鍵索引的查詢需要多掃描一棵索引樹。因此,我們在應用中應該盡量使用主鍵查詢。
索引維護
B+ 樹為了維護索引有序性,在插入新值的時候需要做必要的維護(所以推薦自增主鍵)
中間插入記錄:需要邏輯上挪動后面的數據,空出位置
數據頁滿了: 根據 B+ 樹的算法,這時候需要申請一個新的數據頁,然后挪動部分數據過去(頁分裂,原本放在一個頁的數據,現在分到兩個頁中,整體空間利用率降低大約 50%)
當相鄰兩個頁由于刪除了數據,利用率很低之后,會將數據頁做合并。合并的過程,可以認為是分裂過程的逆過程。
主鍵選擇:主鍵長度越小,普通索引的葉子節點就越小,普通索引占用的空間也就越小,從性能和存儲空間方面考量,自增主鍵往往是更合理的選擇。
業務字段做主鍵:不回表,典型的 KV 場景。
回表
回到主鍵索引樹搜索的過程,稱為回表
覆蓋索引
如果值已經在 某個索引樹上了,因此可以直接提供查詢結果,不需要回表。由于覆蓋索引可以減少樹的搜索次數,顯著提升查詢性能,所以使用覆蓋索引是一個常用的性能優化手段。
最左前綴原則
B+ 樹這種索引結構,可以利用索引的“最左前綴”,來定位記錄。
不只是索引的全部定義,只要滿足最左前綴,就可以利用索引來加速檢索。這個最左前綴可以是聯合索引的最左 N 個字段,也可以是字符串索引的最左 M 個字符。
在建立聯合索引的時候,如何安排索引內的字段順序?
評估標準是,索引的復用能力。因為可以支持最左前綴,所以當已經有了 (a,b) 這個聯合索引后,一般就不需要單獨在 a 上建立索引了。
索引下推
在 MySQL 5.6 之前,只能一個一個回表,到主鍵索引上找出數據行,再對比字段值。
而 MySQL 5.6 引入的索引下推優化(index condition pushdown), 可以在索引遍歷過程中,對索引中包含的字段先做判斷,直接過濾掉不滿足條件的記錄,減少回表次數。
直接判斷age,只需要回表 2 次。
常見的樹結構
二叉樹
二叉樹是一種二分查找樹,有很好的查找性能,相當于二分查找。
但是當N比較大的時候,樹的深度比較高。數據查詢的時間主要依賴于磁盤IO的次數,二叉樹深度越大,查找的次數越多,性能越差。
多叉樹
多叉樹就是節點可以是M個,能有效地減少高度,高度變小后,節點變少I/O自然少,性能比二叉樹好
B樹
B樹簡單地說就是多叉樹,每個葉子會存儲數據,和指向下一個節點的指針。
B+樹
B+樹是B樹的改進,簡單地說是:只有葉子節點才存數據,非葉子節點是存儲的指針;所有葉子節點構成一個有序鏈表
優點:
非終結點并不是最終指向文件內容的結點,而只是葉子結點中關鍵字的索引。所以任何關鍵字的查找必須走一條從根結點到葉子結點的路。所有關鍵字查詢的路徑長度相同,導致每一個數據的查詢效率相當。
紅黑樹
紅黑樹的規則:
1)每個結點要么是紅的,要么是黑的。
2)根結點是黑的。
3)每個葉結點(葉結點即指樹尾端NIL指針或NULL結點)是黑的。
4)如果一個結點是紅的,那么它的倆個兒子都是黑的。
5)對于任一結點而言,其到葉結點樹尾端NIL指針的每一條路徑都包含相同數目的黑結點。
現在想想,理解是平衡樹(AVL)更平衡,結構上更加直觀,時間效能針對讀取而言更高,但是維護起來比較麻煩(插入和刪除之后,都需要rebalance)。但是紅黑樹通過它規則的設定,確保了插入和刪除的最壞的時間復雜度是O(log N) 。
設計紅黑樹的目的,就是解決平衡樹的維護起來比較麻煩的問題,紅黑樹,讀取略遜于AVL,維護強于AVL,每次插入和刪除的平均旋轉次數應該是遠小于平衡樹。
紅黑樹 和 b+樹的用途有什么區別?
總結
以上是生活随笔為你收集整理的深入浅出MySql索引的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python组合数据分类_Python
- 下一篇: caffe源码阅读(1)_整体框架和简介