MySQL索引底层数据结构详情

 更新时间:2021年12月12日 14:31:11   作者:bkpp976  
这篇文章主要介绍了MySQL索引底层数据结构详情,下面文章围绕MySQL索引底层数据结构的相关资料展开全篇文章,具有一定的参考价值,需要的小伙伴可以参考一下

一、索引类型

1.B+树

为什么是B+树而不是B树?

首先看看B树和B+树在结构上的区别

B树结构:

B+树:

可以看到:

  • B树在每个节点上都有卫星数据(数据表中的一行数据),而B+树只在叶子节点上有卫星数据。这意味着相同大小的磁盘扇区,B+树可以存储的叶子节点更多,磁盘IO次数更少;同样也意味着B+树的查找效率更稳定,而B树数据查询的最快时间复杂度是O(1)。
  • B树的每个节点只出现一次,B+树的所有节点都会出现在叶子节点中。B+树的所有叶子节点形成一个升序链表,适合区间范围查找,而B树则不适合。

2.MyISAM和InnoDB的B+树索引实现方式的区别(聚簇索引和非聚簇索引)?

首先需要了解聚簇索引和非聚簇索引。

聚簇索引:

在聚簇索引中,叶子页包含了行的全部数据,节点页值包含索引列。InnoDB通过主键聚集数据,如果没有定义主键则选择一个唯一的非空索引列代替;如果没有这样的索引,InnoDB会隐式定义一个主键来作为聚簇索引。

聚簇索引的数据分布:

 在聚簇索引中,除了主键索引,还有二级索引。二级索引中的叶子节点存储的不是“行指针”,而是主键值,并以此作为指向行的“指针”。这意味着通过二级索引查找行,存储引擎需要找到二级索引的叶子节点获得对应的主键值,然后根据这个值去聚簇索引中查找对应的行,也称为“回表”。当然,可以通过覆盖索引避免回表或者InnoDB的自适应索引能够减少这样的重复工作。

注意:聚簇索引中每一个叶子节点不止包含完整的数据行,还包括事务ID、用于事务和MVCC的回滚指针。

3.非聚簇索引

非聚簇索引的主键索引和二级索引在结构上没有什么不同,都在叶子节点上存储指向数据的物理地址的“行指针”。

聚簇索引的主键索引和二级索引:

非聚簇索引的主键索引和二级索引:

4.聚簇索引的优缺点

优点:

把相关数据保存在一起(比如用用户ID把用户的全部邮件聚集在一起),否则每次数据读取就可能导致一次磁盘IO
数据访问更快,把索引和数据保存在同一个B+树中,通常在聚簇索引中获取数据比在非聚簇索引中查找更快
使用覆盖查询可以直接利用页节点中的主键值

缺点:

如果所有数据都可以放在内存中,顺序访问不再那么必要,聚簇索引没有优势
插入速度依赖于插入顺序,随机插入会导致页分裂,造成空洞,使用OPTIMIZE TABLE重建表
每次插入、更新、删除都需要维护索引的变化,代价很高
二级索引可能比想象中大,因为在节点中包含了引用行的主键列

5.哈希索引

哈希索引基于哈希表实现,只有精确匹配索引所有列的查询才有效,这意味着,哈希索引适用于等值查询。

具体实现:对于每一行数据,存储引擎都会对所有的索引列计算一个哈希码,哈希索引将所有的哈希码存储在索引中,同时在哈希表中保存指向每个数据行的指针。

在MySQL中,只有Memory引擎显式支持哈希索引,当然Memory引擎也支持B树索引。

注意:Memory引擎支持非唯一哈希索引,解决冲突的方式是以链表的形式存放多个哈希值相同的记录指针。

6.自适应哈希索引

InnoDB注意到某些索引值被使用得非常频繁时,会在内存中基于B+树索引之上再创建一个哈希索引,这样就让B+树索引也具有哈希索引的一些优点,比如快速的哈希查找。

到此这篇关于MySQL索引底层数据结构详情的文章就介绍到这了,更多相关MySQL索引底层数据结构内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • MySql CPU激增原因小结

    MySql CPU激增原因小结

    本文主要介绍了MySQL CPU激增的原因和解决方法,包括QPS激增、慢SQL和大量空闲连接导致的CPU升高,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2024-11-11
  • Centos 6.3将Mysql 5.1.61升级为mysql 5.6.19遇到的问题及解决方式

    Centos 6.3将Mysql 5.1.61升级为mysql 5.6.19遇到的问题及解决方式

    mysql5.6.19已经发布很久了,一直没有去升级,最近做项目需要mysql5.5以上,索性直接上5.6.19吧,原本以为升级这种事情,分分钟就完成了,没想到还是出了各种问题,下面把部分记录分享给大家
    2014-07-07
  • MYSQL查询时间范围内的数据示例代码

    MYSQL查询时间范围内的数据示例代码

    这篇文章主要介绍了MYSQL查询时间范围内的数据,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-06-06
  • 关于MySQL存取图片的三种方式(含源码示例)

    关于MySQL存取图片的三种方式(含源码示例)

    最近在做小程序的后台,要求将小程序用户以upload方法上传的图片保存到mysql数据库中,然后机缘巧合三种方式都试了,所以专门整理出来分享给大家,可能有的地方说的不太对,欢迎大家帮纠正,需要的朋友可以参考下
    2024-04-04
  • mysql分页原理和高效率的mysql分页查询语句

    mysql分页原理和高效率的mysql分页查询语句

    这篇文章主要介绍了mysql分页原理和高效率的mysql分页查询语句,大家参考使用吧
    2014-01-01
  • mysql data文件夹位置查找

    mysql data文件夹位置查找

    在mysql安装之后,如何找到自己的mysql数据库的安装位置,本文将介绍详细的解决方法,需要的朋友可以参考下
    2012-12-12
  • 查看连接mysql的IP地址的实例方法

    查看连接mysql的IP地址的实例方法

    在本篇文章里小编给大家分享的是一篇关于查看连接mysql的IP地址的实例方法,有需要的朋友们可以参考下。
    2020-10-10
  • SQL实现LeetCode(196.删除重复邮箱)

    SQL实现LeetCode(196.删除重复邮箱)

    这篇文章主要介绍了SQL实现LeetCode(196.删除重复邮箱),本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下
    2021-08-08
  • 浅谈MySql整型索引和字符串索引失效或隐式转换问题

    浅谈MySql整型索引和字符串索引失效或隐式转换问题

    本文主要介绍了MySql整型索引和字符串索引失效或隐式转换问题,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-11-11
  • MYSQL如何查看进程和kill进程

    MYSQL如何查看进程和kill进程

    这篇文章主要介绍了MYSQL如何查看进程和kill进程,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-03-03

最新评论