據說微信搜索《Java魚仔》會變動強哦!git
本文收錄於JavaStarter ,裏面有我完整的Java系列文章,學習或面試均可以看看哦github
(一)關於索引
索引是幫助Mysql更加高效獲取數據的一種數據結構,索引的使用很簡單,可是若是不能理解索引底層的數據結構的話,就談不上去優化索引了。面試
(二)B+樹
Mysql的索引用的是B+樹,他具備這樣的幾個特色:sql
一、數據都存儲在葉子節點中、非葉子節點只存儲索引數據庫
二、葉子節點中包含全部的索引微信
三、每一個小節點的範圍都在大節點之間數據結構
四、葉子節點用指針相連,提升訪問性能,好比條件是>或者<的查詢就能夠直接按指針找(Mysql中的B+樹葉子節點中的指針是雙向指針)性能
B+樹的數據結構如圖所示,首先非葉子節點只存儲索引,且每一個指針所指向的節點最左邊的索引都是該指針對應的索引值,好比頭節點的第一個索引值8,指向的非葉子節點的第一個索引值也是8。學習
(三)爲何索引這麼快?
索引能夠支撐千萬級表的快速查找,爲何呢?下面就來解釋一下:優化
show GLOBAL STATUS like 'Innodb_page_size'
在Innodb中,默認的innodb_page_size大小爲16kb,這就至關於上面每個節點的大小默認狀況下是16kb。一個索引值的大小爲8B,索引後的指針所佔大小爲4B,所以能夠解算出一個節點中大約能夠存儲1170個索引。
對於葉子節點,因爲存儲了數據,咱們能夠大方地估計每一個數據的大小爲1kb,至關於在葉子節點中每一個節點能夠存儲16個數據。
這樣就能夠計算出一個三層的B+樹結構的索引一共能夠存儲1170117016=2190萬條數據,這就意味着只須要三次磁盤IO,就能夠檢索兩千萬條數據,因而可知索引能夠支撐千萬級表的快速查找。
(四)Innodb索引的實現
Mysql中的存儲引擎有Innodb和Myisam兩種,兩種索引的實現底層雖然都是B+樹,可是實現形式仍是略有不一樣。
Innodb屬於聚簇索引,即葉子節點包含了完整的數據記錄。下面這張圖是innodb的主鍵索引,全部的數據都放在葉子節點中。
Innodb要求表必須有主鍵,而且推薦使用整型的自增主鍵,這也和他索引的實現有關,使用整型能夠更好的進行B+樹的排序,同時採用自增的方式能夠在插入數據時將數據插入到最後一個節點的後一個,而不用對已產生的索引拆分。
非主鍵索引和主鍵索引略有不通,非主鍵索引的葉子節點存儲的是主鍵的key值:
採用這種方式保持了數據的一致性,當新增一條數據時,只須要在主鍵索引處修改數據便可,而不會出現每一個索引各自維護的狀況。第二個優點是節省了存儲的空間,數據只須要保存一份便可。
(五)MyIsam索引的實現
Myisam索引文件和數據文件是分離的,在MyIsam存儲引擎中,新建一張表後會在磁盤中增長三個文件:
.frm 文件存儲的是表結構,.MYI文件存儲的是B+樹的索引表,MYD存儲的是數據,我經過下面這張表展現MyIsam索引:
(六)總結
關於數據庫的索引,絕對是工做中經常使用,面試常考的問題,他過重要了。理解索引底層數據結構更加劇要,這是後續優化的基礎,好了,咱們下期再見!