MySQL哈希索引的数据结构以及索引的优缺点

上一篇文章中,我们专门介绍了BTREE索引的数据结构以及底层实现,现在我们看看其他哈希索引结构的实现,以及索引的优缺点。

1 索引的优缺点

索引可以让服务器快速的定位到表的指定位置。但是这并不是索引的唯一作用,总结下来索引有以下4个优点:

  1. 索引大大减少了服务器需要扫描的数据量。
  2. B-Tree索引可以帮助服务器避免排序和临时表,可以用于 ORDER BY 和 GROUP BY 操作,临时表主要是在去重、排序、分组过程中创建,不需要排序和分组,也就不需要创建临时表。
  3. 由于索引中存储了实际的列值,所以某些查询可以只使用索引就能完成全部查询,甚至避免回表查询。
  4. B-Tree索引数据都是有序的,可以将随机I/O变为顺序I/O,顺序读取不需要进行磁盘寻道,并且只需要很短的磁盘旋转时间,速度会非常快。并且可以利用预读特性,相邻的节点也能够被预先载入。

索引的缺点:

  1. 索引本身也是表,因此会占用存储空间,创建和维护索引需要耗费空间和时间成本,这个成本随着数据量增大而增大;
  2. 构建索引会降低数据表的修改操作(删除,添加,修改)的效率,因为在修改数据表的同时还需要修改索引表。

大多数情况下,中到大型的表索引查询都是比全表扫描要快的。但是对于非常小的表(数据量很少),那么简单的全表扫描更高效。

但是对于特大型的表,建立和维护索引的代价将会随之增长。这种情况下,需要用到一种技术可以直接区分出需要查询的一组数据,而不是一条记录一条记录地匹配,例如可以使用分区技术。

2 哈希索引

哈希索引(hash index)基于哈希表实现。哈希索引通过Hash算法(直接定址法、平方取中法、折叠法、除数取余法、随机数法)将数据库的索引列数据转换成定长的哈希码作为key,将这条数据的行的地址作为value一并存入Hash表的对应位置。

在MySQL中,只有Memeory引擎显式的支持哈希索引,这也是Memory引擎表的默认索引结构,Memeory同时也支持B-Tree索引。并且,Memory引擎支持非唯一哈希索引,如果多个列的哈希值相同(或者发生了Hash碰撞),索引会在对应Hash键下以链表形式存储多个记录地址。

哈希索引还有如下特点:

  1. 哈希索引不支持部分索引列的匹配查找,因为哈希索引始终是使用索引列的全部内容来计算哈希值的。例如,在数据列(A,B)上建立哈希索引,如果查询只有数据列A,则无法使用该索引。
  2. 哈希索引具有哈希表的特性,因此只有精确匹配所有列的查询对于哈希索引才有效,比如=、<>、IN(,因为数据的存储是无序的),且无法使用任何范围查询。
  3. 因为数据的存储是无序的,哈希索引还无法用于排序。
  4. 对于精确查询,则哈希索引效率很高,时间复杂度为O(1),除非有很多哈希冲突(不同的索引列有相同的哈希值),如果发生哈希冲突,则存储引擎必须遍历链表中的所有数据指针,逐行比较,直到找到所有符合条件的行。哈希冲突越多,代价就越大!

基于以上的限制,哈希索引只适用于某些特定的场合,但是一旦适合哈希索引,则它带来的性能提升是非常显著的。

InnoBD引擎有一个特殊的功能叫“自适应哈希索引”。当InnoDB注意到某些索引值被使用得非常频繁时,它会在内存中基于B-Tree索引之上再创建一个哈希索引,这样就让B-Tree索引也具有哈希索引的一些优点,比如快速的哈希查找。但这是一个完全自动的、内部的行为,用于无法控制,但用户可以选择完全关闭该动能。

在使用InnoBD引擎时,我们可以在B-Tree的基础上创建一个伪哈希索引。当然这不是真正的哈希索引,因为还是使用的B-Tree进行查找,但它使用哈希值而不是键本身进行索引查找。

例如,如果需要存储大量的URL并且需要根据URL进行查找,如果使用B-Tree来存储URL,则存储的内容就会很大,因为URL本身就很长。为此,我们可以单独指定一个哈希列并为该列创建索引,并选择一个哈希函数!每次存储、变更URL时,对该URL应用一个函数计算出一个哈希值,存入对应的哈希列中。

在查询时,如果采用体积很小的基于哈希值的索引来查找,则性能会提升很多,唯一的缺点就是需要调用一个哈希函数,为此我们可以使用触发器来实现。

如果出现了哈希冲突,则查询会返回多行数据,为此在查询时还必须带上真正的URL常量值。正确的查询语句为:

select xx from url where url_hash = hash('https://www.baidu.com/') AND url = 'https://www.baidu.com/';

3 全文索引

全文索引是一种特殊类型索引,用于查找文本中的关键词,而不是直接比较是否相等。全文索引的和其他索引的匹配方式完全不一样,全文索引更类似于搜索引擎做的事情,查找条件使用 MATCH AGAINST,而不是普通的 WHERE。

全文索引使用倒排索引实现,它记录着关键词到其所在文档的映射。

MyISAM存储引擎支持全文索引,InnoDB 存储引擎在 MySQL 5.6.4 版本中也开始支持全文索引。

4 空间数据索引(R-Tree)

MyISAM存储引擎支持空间数据索引(R-Tree),可以用于地理数据存储。空间数据索引会从所有维度来索引数据,可以有效地使用任意维度来进行组合查询。

必须使用 GIS 相关的函数来维护数据。

下一篇文章中,我们将介绍一些高性能的索引策略以及索引失效的情况和索引优化策略,在面试中会经常问道。

参考资料:

  1. 《 MySQL 技术内幕: InnoDB 存储引擎》
  2. 《高性能 MySQL》

如有需要交流,或者文章有误,请直接留言。另外希望点赞、收藏、关注,我将不间断更新各种Java学习博客!

  • 13
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论
MySQL哈希索引是一种用于加快数据检索速度的索引结构。哈希索引使用哈希函数将索引键映射到一个固定大小的哈希值,然后将哈希值与存储在内存中的哈希表进行匹配,以快速定位到所需的数据行。哈希索引的搜索时间复杂度为O(1),因为它直接通过哈希值进行查找,而不需要像B树索引那样进行逐层的比较。这使得哈希索引在某些特定场景下具有较高的检索效率。 然而,需要注意的是,MySQL哈希索引并非适用于所有情况。哈希索引的主要限制是它只支持等值查询,而不支持范围查询或排序操作。此外,哈希索引对于频繁的插入和删除操作也不太友好,因为这些操作可能导致哈希冲突,进而影响索引的性能。 此外,MySQL还引入了自适应哈希索引的概念。自适应哈希索引是一种动态索引结构,它根据查询模式自动选择是否使用哈希索引。自适应哈希索引可以根据实际查询情况动态地创建和删除哈希索引,以提高查询性能。但是,创建哈希索引也会消耗一定的资源,因此需要根据具体的衡量参数来决定是否打开或关闭自适应哈希索引。 总结来说,MySQL哈希索引是一种用于加快数据检索速度的索引结构,它具有快速的搜索效率和较低的磁盘IO开销。然而,哈希索引只适用于等值查询,并且对于频繁的插入和删除操作不太友好。自适应哈希索引是一种动态索引结构,可以根据查询模式自动选择是否使用哈希索引,以提高查询性能。 #### 引用[.reference_title] - *1* *2* *3* [Mysql哈希索引](https://blog.csdn.net/Reggie0202/article/details/122238967)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

刘Java

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值