提起MySQL索引,會習慣性想起B(yǎng)+Tree,其實MySQL常用的索引有兩種:
- B+Tree索引
- Hash索引(只有Memory存儲引擎支持)
從名字上可以看到,這兩種索引使用的是兩種不同的數(shù)據(jù)結構,前者是B+Tree,后者是Hash。

Hash索引使用Hash算法(比如CRC32)把鍵值轉(zhuǎn)換成一個hashcode,存放在索引中。在檢索時,不必想B+樹那樣從根到葉子逐級查找,而是一次定位。對于每一行數(shù)據(jù),存儲引擎都會對所有索引計算一個哈希碼,哈希碼是一個較小的值并且不同鍵值計算出來的哈希碼都不一樣。哈希索引將所有的哈希碼存儲在索引中,同時在哈希表中保存指向每個數(shù)據(jù)的指針。
Hash索引的優(yōu)缺點都很明顯:
- Hash 索引僅僅能滿足"=","IN"和"<=>"查詢,不能使用范圍查詢。
- hash索引無法通過操作索引來排序,因為存放的時候經(jīng)過hash計算,但是計算的hash值和存放的不一定相等,所以無法排序
- 哈希索引也沒辦法利用索引完成排序,以及l(fā)ike ‘xxx%’ 這樣的部分模糊查詢(這種部分模糊查詢,其實本質(zhì)上也是范圍查詢)
- 不能避免表掃描。Hash 索引是將索引鍵通過 Hash 運算之后,將 Hash運算結果的 Hash 值和所對應的行指針信息存放于一個 Hash 表中,由于不同索引鍵存在相同 Hash 值,所以即使取滿足某個 Hash 鍵值的數(shù)據(jù)的記錄條數(shù),也無法從 Hash 索引中直接完成查詢,還是要通過訪問表中的實際數(shù)據(jù)進行相應的比較,并得到相應的結果。
- Hash碰撞問題會使索引效率降低