hash索引基于哈希表實現,只有精確匹配索引所有列的查詢才有效。Memory引擎默認使用的是此種索引。
存儲引擎對所有的索隱列計算出一個哈希碼,將哈希碼存儲在索引中,同時哈希表中保存每個數據行的指針。這樣,對于此種索引查找速度是非常快的。出現哈希值碰撞的話,索引會以鏈表的形式存放多個記錄指針到同一個哈希條目中。
舉個??:
name | age |
---|---|
Jane | 28 |
Peter | 20 |
David | 30 |
假設使用假想的哈希函數f(),生成對應的設想值:
f('Jane') = 2323
f('Peter') = 2456
f('David') = 2400
則哈希索引的數據結構如下:
槽(slot) | 值(value) |
---|---|
2323 | 指向第1行指針 |
2400 | 指向第3行指針 |
2456 | 指向第2行指針 |
對于select * from user where `name` = 'Jane'
那么直接先算Jane
的哈希值,然后根據Jane
的hash值2323去找到對應的第一行數據,查詢速度相對于B-Tree索引是要快,但是也有一些局限:
- hash索引中只有hash值和行數的指針,因此無法直接使用索引來避免讀取行,但是因為這種索引讀取快,性能影響不明顯。
- hash索引不是按照索引值順序存儲,無法使用于排序。
- 不支持部分列匹配查找,這里面是使用索引列的全部內容來計算哈希值,例如(A,B)兩列一起建索引,單純使用A一列,那么就無法使用索引,B-Tree索引的話,因為支持匹配最左前綴,所以這種情況適用性偏好。
- 哈希索引只支持等值查詢,包括=、in()、<=>,不支持where age > 10 這種范圍查詢。
- 哈希沖突很多的話,維護索引操作的代價也很高