数据库索引(Hash和B+)

我们知道数据库索引有两种方式
第一:Hash表
第二:B+树

Hash表

哈希索引(hash index)基于哈希表实现,只有精确匹配索引所有列的查询才有效。对于每一行数据,存储引擎都会对所有的索引列计算一个哈希码(hash code),哈希码是一个较小的值,并且不同键值的行计算出来的哈希码也不一样。哈希索引将所有的哈希码存储在索引中,同时在哈希表中保存指向每个数据行的指针。对于hash相同的,采用链表的方式解决冲突。类似于hashmap。因为索引的结构是十分紧凑的,所以hash索引的查询很快。
哈希索引比起B树索引简单,因为它不需要遍历B树,所以访问速度会更快

特点:

1,哈希索引只包含哈希值和行指针,而不存储字段值,所以不能直接使用索引中的值来读取行。
2,哈希索引数据并不是按照索引值顺序存储的,所以也就无法用于排序。
3,哈希索引也不支持部分索引列匹配查找,因为哈希索引始终是使用索引列的全部内容来计算哈希值的。
4,哈希索引只支持等值比较查询,包括=、IN()、<>(注意<>和<=>是不同的操作)。也不支持任何范围查询,例如WHERE price>100。
5,访问哈希索引的数据非常快,除非有很多哈希冲突(不同的索引列值却有相同的哈希值)。当出现哈希冲突的时候,存储引擎必须遍历链表中所有的行指针,逐行进行比较,直到找到所有符合条件的行。
6,如果哈希冲突很多的话,一些索引维护操作的代价也会很高。例如,如果在某个选择性很低(哈希冲突很多)的列上建立哈希索引,那么当从表中删除一行时,存储引擎需要遍历对应哈希值的链表中的每一行,找到并删除对应行的引用,冲突越多,代价越大。

B+树

①.全值匹配:指的是和索引中所有列进行匹配。假设以(姓,名,出生日期)三个数据项建立复合索引,那么可以查找姓名为张三,出生日期在2000-12-12的人

②.匹配最左前缀:假设以(姓,名,出生日期)三个数据项建立复合索引,可以查找所有姓张的人

③.匹配列前缀:假设有姓为司徒的人,我们也可以查找第一列的前缀部分,如查找所有以司开头的姓的人

④.匹配范围值:可以查找所有在李和张之间的姓的人,注意范围查询只在复合索引的优先排序的第一列。(假设姓名按照拼音排序)

⑤.精确匹配前面列并范围匹配后一列:可以查找姓李并出生日期在2000-12-12之后的人或姓名为张三并出生日期在2000-12-12之后的人,注意范围第一个范围查询后面的列无法再使用索引查询

⑥.只访问索引的查询:即查询只需访问索引,而无需访问数据行。

B+ Tree索引缺点
①.如果不是按照索引的最左列开始查找,则无法使用索引。如无法查找名为龙的人,也无法查找在2000-12-12之后出生的人,当然也无法查找姓中以龙结尾的人(注意为和含有的区别)

②.不能跳过索引中的列:无法查找姓李并在2000-12-12之后出生的人

③.如果查询中包括某个列的范围查询,则其右边所有列都无法使用索引优化查询