索引(B+树)、B+树一个节点有多大?(一千万条数据,B+树多高?)

1. 谈谈对索引的理解

  • 索引是存储引擎用于提高数据查询效率的一种数据结构,索引类似于字典里的目录。Mysql中的索引是在存储引擎层实现的,索引的数据结构和存储引擎有关,在MySQL中使用较多的索引有 Hash 索引、B树索引和 B+ 树索引。

    • hash索引:底层就是 hash 表。进行查找时,根据 key 调用hash 函数获得对应的 hashcode,根据 hashcode 找到对应的数据行地址,根据地址拿到对应的数据。
    • B树索引:B树是一种多路搜索树,n 路搜索树代表每个节点最多有 n 个子节点。每个节点存储 key + 指向下一层节点的指针+ 指向 key 数据记录的地址。查找时,从根结点向下进行查找,直到找到对应的key。
    • B+树索引:B+树是b树的变种,主要区别在于:B+树的非叶子节点只存储 key + 指向下一层节点的指针,也就是只存索引,不存数据,数据都保存在叶子节点中。另外,B+树的叶子节点之间通过指针来连接,构成一个有序链表,因此对整棵树的遍历只需要一次线性遍历叶子结点即可。
  • 索引有三个优点: ①减少了服务器需要扫描的数据量;②帮助服务器避免排序;③将随机IO变为顺序IO,因为 B+ 树索引是有序的,它将相邻的数据都存储在一起。

  • 索引的缺点:创建索引和维护索引会耗费时间;索引会占用物理空间;当对表进行增删改时,索引也需要动态维护,这样会降低数据的维护速度。一般在频繁使用或需要排序的字段上建立索引,而对于很少查询或重复值较多的列,不适合建立索引。、、

(InnoDB 中使用了 B+ 树索引,它先通过 B+ 树找到数据所在的页,然后将页读到内存,在内存中找到要查找的数据。Mysql 将索引存放在磁盘而不是内存中,减少了内存消耗)

2. B树和B+树的区别?为什么使用B+树?(B+树底层文件是怎么存储的)

  • B+树的中间节点存的是索引,不存储数据,数据都保存在叶子节点中,而B树的所有节点都能存放数据。所以B+树 磁盘读写的代价比B树低,因为中间节点不放数据,所以相同的磁盘块能存放更多的节点,一次性读入内存的节点数量也就越多,所以IO读写次数就降低了。
  • B+树的叶子节点位于同一层,数据也都位于叶子节点中,所以每次查找都是从根节点找到叶子节点,效率很稳定。而B树在查到关键字后就停止查找了,效率不够稳定。
  • B+树的叶子节点还按照大小,通过链表有序的串联在一起,在进行遍历查询时,只需要遍历这个链表即可,而且还支持范围查询,查到范围的开始节点,然后往后遍历即可实现。而B树没有这样的链表,只能通过中序遍历来查找数据,不支持范围查询。

3. MySQL为什么要用B+树存储索引?而不用平衡二叉树(红黑树)、Hash索引(散列表)、B树、跳表?

  • Hash索引(散列表):如果只查询单个值的话,hash 索引的效率非常高,时间复杂度为O(1)。但是 hash 索引有几个问题:1)不支持范围查询;2)不支持索引值的排序操作;3)不支持联合索引的最左匹配规则。
  • 平衡二叉树(红黑树):查询性能也好,时间复杂度O(logn),中序遍历可以得到一个从小到大有序的数据序列,但不支持区间查找。而且由于是二叉树,当数据量很大时树的层数就会很高,从树的根结点向下寻找的过程,每读1个节点,都相当于一次IO操作,因此他的I/O操作会比B+树多的多。
  • B树索引:见上面B树和B+树的区别↑。
  • 跳表:是一种链表加多层索引的结构,时间复杂度O(logn),支持区间查找,而B+树是一种多叉树,可以让每个节点大小等于操作系统每次读取页的大小,从而使读取节点时只需要进行一次IO即可。而且同数量级的数据,跳表索引的高度会比 B+ 树的高,导致 IO 读取次数多,影响查询性能。

4. B+树一个节点有多大?一千万条数据,B+树多高?

  • B+树一个节点的大小设为一页或页的倍数最为合适。因为如果一个节点的大小 < 1页,那么读取这个节点的时候其实读取的还是一页,这样就造成了资源的浪费。
  • 在 MySQL 中 B+ 树的一个节点大小为“1页”,也就是16k。之所以设置为一页,是因为对于大部分业务,一页就足够了:
    • 首先InnoDB的B+树中,非叶子节点存的是key + 指针;叶子节点存的是数据行。
    • 对于叶子节点,如果一行数据大小为1k,那么一页就能存16条数据;对于非叶子节点,如果key使用的是bigint,则为8字节,指针在mysql中为6字节,一共是14字节,则16k能存放 16 * 1024 / 14 = 1170 个索引指针。于是可以算出,对于一颗高度为2的B+树,根节点存储索引指针节点,那么它有1170个叶子节点存储数据,每个叶子节点可以存储16条数据,一共 1170 x 16 = 18720 条数据。而对于高度为3的B+树,就可以存放 1170 x 1170 x 16 = 21902400 条数据(两千多万条数据),也就是对于两千多万条的数据,我们只需要高度为3的B+树就可以完成,通过主键查询只需要3次IO操作就能查到对应数据。所以在 InnoDB 中B+树高度一般为3层时,就能满足千万级的数据存储,所以一个节点为1页,也就是16k是比较合理的。
  • 35
    点赞
  • 98
    收藏
    觉得还不错? 一键收藏
  • 9
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值