MySQL索引是在面试中常被问到的知识点,常用的两种索引方法有Hash和B+Tree,树的结构我们改天再扯,今天说收Hash。
为什么使用hash
Hash索引可以根据数据的hash值直接定位到索引数据的存储位置,就相当于我知道了数组的下标,然后根据下标去取数据,这个效率可以说是最高的了,使用hash就是为了如此。
支持hash的存储引擎
目前支持hash的引擎有MEMORY(这里需要谷歌),其他的引擎都通过各自的方式去支持hash方法。如InnoDB有一套自适应hash算法,内部实现还是采用了BT的方式,可以理解为BT索引的索引
InnoDB中hash索引支持的开启/关闭
hash索引虽然非常快速,但是在InnoDB中确实支持的不是很好,并且索引的具体创建是由引擎决定的(创建后存在于内存中),非DBA可控,所以一般情况下建议关闭hash支持,使用BT也能够满足性能要求。
set global innodb_adaptive_hash_index=off/on
hash的使用场景
hash使用场景比较局限
- hash索引仅适用于‘=’、‘<=>’和‘in’操作,所以hash仅仅适用于精确查找。
- 不适用于查询排序,因为hash后的数据并不会像原数据一样保持有序。
- 不适用于模糊查询,也就是不能使用like关键字。
- 既然不支持排序,也肯定不支持范围查询咯
解决hash冲突
不论hash的算法多么精确,当数据量大的时候都有可能发生hash碰撞,解决hash碰撞的方法有很多,比如再hash、链表叠加等,MySQL采用的是链表叠加的方式,也就是类似于HashMap解决hash碰撞的方法。所以在发生hash碰撞过多的情况下,使用hash索引会影响查询性能。