MySQL底层索引与算法

本文深入探讨了MySQL底层索引机制,包括二叉树、红黑树、B树和B+树的数据结构及其优缺点。重点介绍了B+树如何降低查询复杂度,以及为何MySQL选择B+树作为索引结构。此外,还讨论了聚集索引、非聚集索引的区别,以及InnoDB中主键和自增主键的重要性。最后,提到了索引的最左前缀原则及回表现象,强调了索引设计对查询性能的影响。
摘要由CSDN通过智能技术生成

MySQL底层索引与算法

索引数据结构

索引是帮助MySQL高效获取数据的排好序的数据结构

二叉树:

在这里插入图片描述

  • 如果索引的结构使用二叉树对col2lie建立索引,索引结构如上图右侧所示。
    比如select * from table where col2=89;
    此时如果不适用索引查询则会逐行查询遍历6次,才能查到对应的值,如果使用索引,则查询2次,便可查询到对应的数据;效率明显提高
    但是如果对于col1之类逐行递增的数据,二叉树形成的数据结构如图所示:
    在这里插入图片描述
  • 此时如果执行SQL select * from table where col1=6;则和全表扫面一样,需要扫描6次才能找到对应的数据。所以不可取

红黑树:

在这里插入图片描述

  • 红黑树可以解决 单列逐行递增的问题,但是会暴露一个新的问题,就是如果数据量过大的情况下,树的高度会变的很高,如果数据位于叶子节点,也需要查询很多次才能查到数据,效率不够高。

B树

  1. 叶节点具有相同的深度,叶节点的指针为空
  2. 所有索引元素不重复
  3. 节点中的数据索引从左到右递增排列

为了降低红黑树,树的高度过高的问题,则考虑使用B树,在一个节点上放多个元素,则可以有效的降低树的高度。
在这里插入图片描述
而MySQL则使用的是B+树,在B树的基础上做了些变种

B+树(B树变种)

  1. 非叶子节点不存储data,只存储索引(冗余),可以放更多的索引
  2. 叶子节点包含所有索引字段
  3. 叶子节点用指针连接,提高区间访问的性能(可以快速的查到相邻磁盘上的数据)
    在这里插入图片描述
    MySQL对每个叶子的大小分配了16KB的内存(如果每页分配的数据过大,则会降低读取、处理速度),所以降低了树的高度

hash结构

  • 对索引的key进行一次hash计算就可以定位出数据存储的位置
  • 很多时候Hash索引要比B+ 树索引更高效
  • 仅能满足 “=”,“IN”,不支持范围查询
  • hash冲突问题
    在这里插入图片描述

为什么不使用B树作为索引结构?

  1. B树把data数据放在自己所属的每个分页,导致每个分页能够储存的数据变少,以至于储存同样多的数据,相比于B+树 增加了树的高度。B+树把data数据移到叶子节点,就是为了在肥哦叶子节点上存储更多的索引数据,达到减少树的高度的目的。非叶子节点存放的数据越多,树的高度就越低。
  2. B+叶子节点使用指针链接,可以实现范围查询时快速定位到符合条件的数据

聚集索引:叶节点包含了完整的数据记录
非聚集索引:索引文件和数据文件是分离的

数据引擎
  • MyISAM索引文件和数据文件是分离的(非聚集)
    MyISAM对应在磁盘上的数据是分为三个表来存储,一个数据表结构文件,一个索引文件,还有一个数据文件。
    • 查找时通过B+ 树遍历到叶子节点,而叶子节点中data存储的时当前这条数据在数据文件中的位置,拿到这个位置之后到数据文件中找到相应的位置。

在这里插入图片描述

  • InnoDB索引实现(聚集)

    • 表数据文件本身就是按B+Tree组织的一个索引结构文件
    • 聚集索引—叶节点包含了完整的数据记录
    • 为什么建议InnoDB表必须建主键,并且推荐使用整型的自增主键?
    1. 因为为了形成B+树的树形结构,如果没有主键的话,InnoDB会从第一列开始选择一列所有元素都不相等的来形成B+树,如果从第一列一直到最后一列都没有选到的话,则会建立一个隐藏列类似rowId,隐藏列会维护一个唯一的id,来形成B+树,组织整张表的数据。 如果有主键的话,则直接使用主键来形成B+树。
    2. 使用整形自增,而不使用UUID,是因为在寻找元素的时候是从根节点开始寻找,会一直存在比大小的操作,显然 整型值比大小 效率高于 UUID字符串比大小。而且整形值所占用的空间也比UUID字符串占用的空间少
    3. 如果插入非自增索引,如果需要插入的B+树叶子节点数据已经放满,则会导致节点分裂,重新平衡,相比于插入自增索引,重新开一个叶子节点效率更低。
    • 为什么非主键索引结构叶子节点存储的是主键值?(一致性和节省存储空间)

主键索引
二级索引

联合索引

最左前缀原理
储存时按照索引的顺序,依次排序,优先对最左边的列进行排序,如果第一列的索引相等再比较第二列,否则不会对第二列进行排序。第三列同理。如果三列都相同,则依次通过主键去聚合索引里面去查找
在这里插入图片描述

# 根据上图的索引,以及索引最左前缀原理
select * from table where name='Bill'  and age='30';  # 走索引
select * from table where  age='30' and position='dev'; #不走索引
select * from table where position=''; #不走索引

回表:是指通过二级索引或者符合索引查到到对应的叶子节点上对应的data(主键索引), 再通过主键索引到聚合索引中查询对应的数据。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值