mysql专区_MySQL-技术专区-详解索引原理
學習任何技術,首先我們要知道怎么用,熟練之后再探究其原理,最后再根據業務進行優化。?——船長
MySQL的索引有哪些?
主鍵索引:表的主鍵列會默認添加索引,索引中保存了該行記錄的所有數據唯一索引(upique):該列的所有值必須唯一普通索引(normal):普通列的一種索引聚合索引:是普通索引中的一種,但是它是由多個列組成的索引
索引怎么用?
假設我們有幾張表,如下
使用navicat設計學生student表,并添加索引如下
1、主鍵索引
mysql會為每個表的主鍵自動添加索引,在其索引樹的葉子節點中,保存著主鍵所在行的所有數據,這個后面會講。也就是說只要找到主鍵,就代表找到了該行記錄,所以使用了主鍵索引速度會比較快
2、唯一索引
唯一索引對應的列,其數據不可重復,這點相當于主鍵,不同的是其索引樹的葉子節點保存的不是所在行的所有數據,而是該列的值,查詢速度比主鍵慢一些
3、普通索引
普通索引就沒什么好說了,其值可以重復,而且索引樹葉子節點保存的就是該列的值,而不是整行數據
4、聚合索引
當需要聯合幾個字段去查詢時,使用聚合索引的速度會比多個普通索引快,因為每個索引對應一棵索引樹,多個普通索引,雖然都用上了索引,但是要遍歷好幾個索引樹,而使用聚合索引只需遍歷一棵索引樹
如果對索引樹一點了解都沒有的同學,可以先看看下面的分析,再回過頭來理解一下這四種索引,必然會有煥然一新的感覺
索引的底層結構是什么?
索引底層結構分為全文索引、哈希索引、B+樹索引全文索引:只有MyISAM引擎支持,不作介紹哈希索引:計算索引列的hashCode,并將其存在索引中,如果出現沖突,就以鏈表的形式存儲,類似hashMap結構B+樹索引:
將索引列的值排序,并放入索引樹中的指定位置(Mysql默認的索引結構)
哈希索引的原理
hash是一種key-value形式的數據結構,哈希索引是以索引列的hashCode為鍵,數據行的地址指針為值形成的一種索引,它是一塊非常緊湊的地址空間,可以將其視為數組
如果我們要查詢【劉備】,那么先通過計算哈希碼hashCode(劉備)=002得到,然后在哈希索引中找到key=002的位置,拿到真正保存數據的磁盤地址311,再去找到數據行。
可見這里查找了兩次,第一次是根據hashCode找到地址,第二次是根據地址找到數據行,但是這種查詢速度是非常快的,因為它沒有去遍歷每一條數據行,而是通過hashCode直接找到數據行的磁盤地址。
那如果發生hash沖突怎么辦呢?例如關羽和張飛的hashCode都等于010,這時候就會將張飛接在關羽的后面,形成一種鏈式結構,然后在關羽的下一個地址指針中保存張飛的地址。
當查找【張飛】時,通過hashCode(張飛)=010找到地址45,再通過地址找到了關羽,通過判斷姓名【張飛】!=【關羽】,于是通過下一個地址指針46繼續查找,第二次就找到了張飛。
這種解決沖突的方式稱之為鏈地址法。所以哈希索引的結構就是數組+鏈表的形式,與hashMap雷同,但是當沖突太多導致鏈表很長時,操作數據的時候還是會一直遍歷鏈表才能找到數據,這就會影響性能。
大家可以通過哈希索引的結構,再根據自己平時寫sql用到的條件,思考一下他有什么優缺點,我將在文末進行總結。
B+樹索引原理
B+樹的演變
二叉樹 ——> 二叉搜索樹 ——> 平衡二叉樹 ——>B樹 ——>B+樹
在這里對二叉樹等結構不做深入介紹,后續的算法章節會詳細介紹,只簡單介紹B樹和B+樹。
什么是B樹?
基本定義:
1、根節點至少有兩個子節點
2、葉子節點都在同一高度
3、如果非葉子節點有n個關鍵字,那么他有n+1個子節點,且這n個節點遞增排列
什么是B+樹?
B+是由B樹演變而來的,所以它具有B樹的所有特性,另外還有兩點
1、B+樹的非葉子節點只存關鍵字,不存放數據
2、B+樹的葉子節點之間用指針相連,是一個雙向鏈表
MySQL中的B+樹索引
我們用上面的student表來看B+樹是如何存儲索引的,假設在student表中添加以下幾條數據
上面我們已經為其添加了索引,現在student中的所有索引如下
id:主鍵索引,默認創建的
code:唯一索引
class_id:普通索引
name_class:name列和class_id列的聚合索引
id索引的B+樹索引結構
由此可知,主鍵索引的葉子節點存儲了整行的記錄,所以使用了主鍵索引的sql查詢速度是非常快的。
唯一索引和普通索引一樣,只不過該索引的值是唯一的,不會出現重復值
普通列class_id的索引樹
可見其葉子節點保存的是其行記錄中的id,我們看下面兩條sql有何不同
sql1:select * from tb_student where class_id=834
sql2:select id from tb_student where class_id=834
看似一樣,實則不然。第一條sql查詢的是整行記錄,而行記錄是保存在主鍵的索引樹中的,所以其查詢步驟是:根據普通索引class_id的索引樹找到葉子節點,獲得行記錄id,然后根據id去主鍵索引樹中取出整
行記錄這個查詢過程就稱之為回表,可見回表會降低查詢效率
而第二條sql查詢的就是id,class_id的索引樹葉子節點保存的就是id的值,那么不需要去主鍵索引樹取值了,直接將id返回即可,所以效率較前者高。(看到這里大家應該能想到為什么需要聚合索引了)
知其然,知其所以然,必百戰百勝。
聚合索引的樹結構
為了數據能夠直觀一點,我們新增一個聚合索引
其索引樹如下
聯合索引中的第一個索引是classid,那么索引樹會先根據class_id去排序,而后再依次根據后面的索引列排序。所以聯合索引的最左原則就可以在此體現了。
SELECT * FROM tb_student where class_id=18 and id=834
對于上面這條語句,他有兩個索引可以走,第一是聯合索引id_class,第二個是主鍵索引id,拿到底會走哪一條呢?答案是主鍵索引
注意:聯合索引和主鍵索引同時存在時,優先走主鍵索引
為什么呢?這是mysql采用的優化策略,因為主鍵索引可以直接查出整行數據,所以不管你select *還是select 其他字段我都能滿足,而走聯合索引且select *時還會涉及到一次回表操作
總結
哈希索引的優缺點
優點:
1、查詢速度快
2、維護索引的成本相對較低
缺點:
1、無法進行范圍查詢,因為是通過計算元素的hashCode定位查找的,像age>50這種范圍查找是無法使用哈希索引的
2、無法通過索引排序,哈希的最大特點就是散列分布,幾乎毫無規律,所以無法排序
B+樹索引的優缺點
優點:
1、索引樹一般2-4層,查詢效率高,IO消耗少
2、支持各種范圍查詢
3、支持索引排序
缺點:
1、維護索引樹的代價高
2、索引太多所占的空間也會變大
總結
以上是生活随笔為你收集整理的mysql专区_MySQL-技术专区-详解索引原理的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: mysql 手机号 字段_2021-01
- 下一篇: mysql 自后向前截取函数_【转载】S