Hash索引和B+树索引有什么区别或者说优劣势?
首先要知道Hash索引和B+树索引的底层实现原理:
hash索引底层就是hash表,进行查询时,调用一次hash函数就可以获取到相应的键值,之后进行回表查询获得实际数据.
B+树底层实现原理是多路平衡查找树,对于每一次的查询都是从根节点出发,查询到叶子节点方可以获得所查键值,然后查询判断是否需要回表查询.
区别:
hash索引
1:hash索引进行等值查询更快(一般情况下)但是却无法进行范围查询.因为在hash索引中经过hash函数建立索引之后,索引的顺序与原顺序无法保持一致,不能支持范围查询.
2:hash索引不支持模糊查询以及多列索引的最左前缀匹配,因为hash函数的不可预测,eg:AAAA和AAAAB的索引没有相关性.
3:hash索引任何时候都避免不了回表查询数据.
4:hash索引虽然在等值上查询叫快,但是不稳定,性能不可预测,当某个键值存在大量重复的时候,发生hash碰撞,此时查询效率可能极差.
5:hash索引不支持使用索引进行排序,因为hash函数的不可预测.
B+树
1:B+树的所有节点皆遵循(左节点小于父节点,右节点大于父节点,多叉树也类似)自然支持范围查询.
2:在符合某些条件(聚簇索引,覆盖索引等)的时候可以只通过索引完成查询.不需要回表查询.
3:查询效率比较稳定,对于查询都是从根节点到叶子节点,且树的高度较低.
结论
大多数情况下,直接选择B+树索引可以获得稳定且较好的查询速度,而不需要使用Hash索引.
上面提到了B+树在满足聚簇索引和覆盖索引的时候不需要回表查询数据,什么是聚簇索引呢?
聚簇索引:表数据按照索引的顺序来储存的,也就是说索引项的顺序与表中记录的物理顺序一致.在B+树的索引中叶子节点可能储存了当前的key值,也可能储存了当前的key值以及整行的数据,在一张表上最多只能创建一个聚簇索引,因为真实数据的物理顺序只有一种.
非聚簇索引:表数据存储顺序与索引顺序无关,对于非聚簇索引,叶子节点包含索引字段值及指向数据页数据行的逻辑指针.
聚簇索引和非聚簇索引总结: 聚簇索引是一种稀疏索引,数据页的上一级的索引页储存的是页指针,而不是行指针,而非聚簇索引,则是密集索引,在数据页的上一级索引页它为每一个数据行存储一条索引记录.
在InnoDB中,只有主键索引是聚簇索引,如果没有主键,则挑选一个唯一键建立聚簇索引,如果没有唯一键,则隐式的生成一个键建立索引.
当查询使用聚簇索引时,在对应的叶子节点,可以获得到整行数据,因此不用再次进行回表查询.
非聚簇索引一定会回表查询吗?
不一定,这涉及到查询语句所要求的字段是否全部命中了索引,如果全部命中了索引,那么就不必在进行回表查询了.
eg:假设我们在员工表的年龄上建立了索引,那么当进行select age from employee where age<20的查询时,在索引的叶子节点上,已经包含了age信息,不会再次进行回表查询.