噢,他明白了,河水既沒有牛伯伯說的那麼淺,也沒有小松鼠說的那麼深,只有本身親自試過才知道。mysql
看了不少關於索引的博客,講的大同小異。可是始終沒有讓我明白關於索引的一些概念,如B-Tree索引,Hash索引,惟一索引….或許有不少人和我同樣,沒搞清楚概念就開始研究B-Tree,B+Tree等結構,致使在面試的時候答非所問!面試
索引是幫助MySQL高效獲取數據的數據結構。sql
提升數據查詢的效率。數據庫
索引:排好序的快速查找數據結構!索引會影響where後面的查找,和order by 後面的排序。微信
1. 從存儲結構上來劃分:BTree索引(B-Tree或B+Tree索引),Hash索引,full-index全文索引,R-Tree索引。數據結構
2. 從應用層次來分:普通索引,惟一索引,複合索引。spa
3. 根據中數據的物理順序與鍵值的邏輯(索引)順序關係:彙集索引,非彙集索引。指針
1 中所描述的是索引存儲時保存的形式,2 是索引使用過程當中進行的分類,二者是不一樣層次上的劃分。不過平時講的索引類型通常是指在應用層次的劃分。code
就像手機分類,安卓手機,IOS手機 與 華爲手機,蘋果手機,OPPO手機同樣。blog
mysql默認存儲引擎innodb只顯式支持B-Tree( 從技術上來講是B+Tree)索引,對於頻繁訪問的表,innodb會透明創建自適應hash索引,即在B樹索引基礎上創建hash索引,能夠顯著提升查找效率,對於客戶端是透明的,不可控制的,隱式的。
不談存儲引擎,只討論實現(抽象)
基於哈希表實現,只有精確匹配索引全部列的查詢纔有效,對於每一行數據,存儲引擎都會對全部的索引列計算一個哈希碼(hash code),而且Hash索引將全部的哈希碼存儲在索引中,同時在索引表中保存指向每一個數據行的指針。
B-Tree能加快數據的訪問速度,由於存儲引擎再也不須要進行全表掃描來獲取數據,數據分佈在各個節點之中。
是B-Tree的改進版本,同時也是數據庫索引索引所採用的存儲結構。數據都在葉子節點上,而且增長了順序訪問指針,每一個葉子節點都指向相鄰的葉子節點的地址。相比B-Tree來講,進行範圍查找時只須要查找兩個節點,進行遍歷便可。而B-Tree須要獲取全部節點,相比之下B+Tree效率更高。
案例:假設有一張學生表,id爲主鍵
在MyISAM引擎中的實現(二級索引也是這樣實現的)
在InnoDB中的實現
問:爲何索引結構默認使用B-Tree,而不是hash,二叉樹,紅黑樹?
hash:雖然能夠快速定位,可是沒有順序,IO複雜度高。
二叉樹:樹的高度不均勻,不能自平衡,查找效率跟數據有關(樹的高度),而且IO代價高。
紅黑樹:樹的高度隨着數據量增長而增長,IO代價高。
問:爲何官方建議使用自增加主鍵做爲索引。
結合B+Tree的特色,自增主鍵是連續的,在插入過程當中儘可能減小頁分裂,即便要進行頁分裂,也只會分裂不多一部分。而且能減小數據的移動,每次插入都是插入到最後。總之就是減小分裂和移動的頻率。
插入連續的數據:
插入非連續的數據: