在MySQL里常用的索引数据结构有B+树索引和哈希索引两种
是什么?
哈希索引
HASH:以KV的形式检索数据,也就是说,它会根据索引字段生成哈希码和指针,指针指向数据
哈希索引有什么特点呢?
- 第一个,它的时间复杂度是O(1),查询速度比较快,因为哈希索引里面的数据不是按照顺序存储的,所以不能用于排序
- 第二个,我们在查询数据的时候要根据键值计算哈希码,所以它只能支持等值查询(=N),不支持范围查询(> < >= <= between and)
- 第三个,如果字段值很多的时候,会出现大量的哈希冲突,效率会降低
简单来说,哈希索引就是采用一定的hash算法,把键值换算成新的hash值,检索时不需要类似的B+那样从根节点到叶子节点逐级查找,只需要一次hash算法就可以立即定位到相应位置,速度非常快。
B-Tree索引
B-Tree能够加快数据的访问速度,因为存储引擎不再需要进行全表扫描,数据分布在各个节点中
B+Tree索引
B+树是B-树的改进版本,数据都在叶子节点上,并且增加了顺序访问指针,每个叶子节点都指向相邻的叶子节点的地址。
- 相比B-Tree来说,进行范围查询时只需要查找较小的那个节点,然后顺着节点直接遍历即可
- 而B-Tree需要获取所有节点,相比之下B+Tree效率更高
区别与联系
二者区别
从上面来看,B+树索引和Hash索引的区别是:
- 如果是等值查找,那么hash索引具有明显优势。因为只需要经过一次算法就可以找到响应的减值;当然,这个前提是,减值都是唯一的。如果减值不唯一,那么就需要先找到键值所在的位置,然后再扫描链表,知道直到对应的数据
- 如果是范围查找,hash索引也无法作用,因为原先是有序的键值,经过hash算法之后,有可能变得不连续了,就没有办法利用索引完成范围hash查找检索了
- 同理,hash索引也没有版本利用索引完成排序,以及like ‘xxx%’ 这样的部分模糊查询(这种部分模糊查询,其实本质上也是范围查询);
- hash索引也不支持多列联合索引的最左匹配原则
- B+树索引的关键字检索效率比较平均,不像B树那样波动幅度大,在有大量重复键值情况下,哈希索引的效率也是极低的,因为存在所谓的哈希碰撞问题。
总的来说: hash索引能以O(1)时间进行查找,但是失去了有效性。无法用于排序和分组,只支持精确查找,无法用于部分查找和范围查找
联系
- InnoDB存储引擎只显示支持B+数索引。对于频繁访问的表,InnoBD会透明建立自适应的hash索引,即在B树索引的基础上建立hash索引,可以显示提高查询效率
- InnoDB 存储引擎有一个特殊的功能叫“自适应哈希索引”,当某个索引值被使用的非常频繁时,会在B+树索引之上再创建一个hash索引,这样就让B+Tree索引具有hash索引的一些优点。
- 在MySQL中,只有Heap/Memory引擎表才能显式的支持hash索引(NDB也支持,但这个不常用)
- 还要注意到:Heap/Memory引擎表在MySQL实例重启后,数据就会丢失。
问题:InnoDB可以在客户端创建一个索引,使用哈希索引吗?
问题:
在Navicat的工具中,创建索引,方式有两种:Hash和BTree
是不是说InnoDB可以在客户端创建一个索引,使用哈希索引吗?
回答
-
InnoDB内部使用哈希索引来实现自适应哈希索引特性。这句话的意思是InnoDB只支持显示创建B+Tree索引,对于一些热点数据页,InnoDB会自动建立自适应Hash索引,也就是在B+.Tree索引基础上建立Hash索引,这个过程对于客户端是不可控制的,隐式的
-
我们在Navicat工具里面选择索引方法是hash,但是它创建的还是B+Tree索引,这个不是我们可以手动控制的
后记
通常,B+树索引适合绝大多数场景,
- 在Heap表中,如果存储的数据重复度很低(也就是说技术很大),对该列数据以等值查询为主,没有范围查找、排序时,特别适合采用哈希索引。例如这种SQL:SELECT … FROM t WHERE C1 = ?; — 仅等值查询
- 在大多数场景下,都会有范围查询、排序、分组等查询特征,用B+树索引就可以了。