首先,只有Memory引擎支持Hash索引。InnoDB引擎可以采用伪Hash索引。
可以把索引列看作key,把一条记录看作一个对象即value,实际上value存储的是一个指针,对应该记录的地址。
进行这么一个查询:
select * from students where name ='张三'
在students表的name列上建了hash索引。步骤如下:
- 通过某个hash函数对索引列进行计算:f('张三'),得到一个整数
- 用上一步的结果跟索引表(可以简单的把它看作一个数组)长度进行&操作得到一个数组下标(其结果一定是小于等于索引表长度的)
- 直接定位到该索引表下标对应位置,得到一个链表,依次用'张三'跟该链表上的对象的key进行比较,找到对应的记录最终返回。
- 插入同理。
关键点:
- 为什么查询快?
其实就是应用了数组查询快的优点。通过对索引列值hash后直接就得到了索引表下标,直接就可以定位到该地址。上面说过可以把索引表看作一个数组,那么已知数组下标k情况下,通过数组基址+k*数组元素长度做寻址操作就可以直接定位到该地址,无需遍历,贼快。
2. 为什么不适用于区间查询,如>、<?
因为hash后的值是无序的,无法进行判断。比如要查询>3的记录,hash(3) 跟 hash(4) 的结果是不确定的,hash(3)不一定就小于hash(4),所以无法通过hash(3)来判断出数组中哪些位置上的记录是>3的。