在MySQL中索引是在存儲引擎層實現的,而不是在服務器層實現的。所以,不一樣的存儲引擎實現也是不一樣的。<br>mysql
B-Tree索引:<br> Innodb引擎使用B+Tree實現<br> MyISAM使用前綴壓縮技術使得索引更小,InnoDb按照原數據格式進行存儲。<br>sql
MyISAM索引經過數據的物理位置引用被索引的行,而InnoDB根據主鍵引用被索引的行。<br>服務器
B-Tree索引可以加快數據的訪問速度,由於存儲引擎不須要全表掃描來獲取須要的數據,而是從索引的根節點開始進行搜索,跟節點的槽中存放了指向子節點的指針,存儲引擎根據指針向下層查找,這些節點定義了子節點的上限和下限;<br>數據結構
B-Tree索引列是順序組織的,因此很適合查找範圍數據,像「找出I到K開頭的名字」,查詢效率很是高。<br>函數
B-Tree索引適用於全值匹配、匹配最左前綴、匹配列前綴、匹配範圍值、精確匹配某一列而且範圍匹配另外一列、只訪問索引的查詢。<br>優化
由於B-Tree索引樹中的節點是有順序的,因此索引還能夠用於order by操做。指針
B-Tree索引的限制:<br>code
所以,索引列的順序很是重要!!!<br>排序
Hash索引:<br> Hash索引是基於Hash表實現的,只有精確匹配的查找纔能有效。對於每一行數據,存儲引擎對全部的索引列計算一個Hash碼,不一樣的建值計算出來的Hash碼不同,Hash索引將全部的Hash碼存儲在索引中,同時在索引中保存指向每一個數據行的指針。<br> 例如:對fname創建hash索引<br>索引
mysql> select * from testhash;
fname | lname |
---|---|
Jack | Lentz |
Tom | James |
Kobe | Zaitsev |
Vadim | Tkachenko |
假設該索引使用Hash函數f(),返回下面的值<br>
f('Jack') = 2233<br> f('Tom') = 6890<br> f('Kobe') = 5678<br> f('Vadim') = 9881<br>
在Hash槽中有以下數據結構<br>
槽(Slot) | 值(value) |
---|---|
2233 | 第一行數據 |
5678 | 第三行數據 |
6890 | 第二行數據 |
9881 | 第四行數據 |
在Hash槽是有序存儲的,可是數據行是無序的。<br>
mysql> select lname from testhash where fname = 'Kobe'
MySql存儲引擎先計算Kobe的hash值,而且找到對應記錄的指針,而後找到第三行的值,比較是否爲Kobe,確保就是要查找的行。<br> Hash索引的限制:<br>
Hash索引不是按照索引值的順序存儲的,所以不能用於order by排序。
Hash索引不支持匹配查找。
Hash索引不支持任何的範圍查找。
當出現Hash衝突時,存儲引擎必須遍歷全部行的指針,逐行比較。
索引的優勢:<br>
大大減小服務器須要掃描的數據量<br>
幫助服務器避免排序和臨時表的建立<br>
索引可以把隨機IO變爲順序IO