索引原理以及B+Tree,看完就懂的索引知识,最适合刚接触索引的人观看

一、索引是什么

简单理解:索引是一种排好序数据结构

可以理解为索引是一种数据文件也是一种数据结构

1)索引是一种特殊的数据文件

        ①MyISAM存储引擎中:数据文件和索引文件是分开的,索引文件保存的是数据记录的地址。

        ②InnoDB存储引擎中:表数据本身就是按照B+Tree的存储的索引结构。在InnoDB查询数据文件时,.ibd文件就是数据+索引存储文件

2)索引是一种数据结构

        ①索引是一种独立的,物理的(真实存在的)数据结构,它是由一个表中的一个字段或者多个字段的值组成的集合。

我们要知道MySQL默认使用B+Tree结构管理索引

二、聊一聊为什么索引要使用B+Tree管理

如上述此表无索引,查找语句需要从磁盘一条一条的对比,如果表特别大,io特别多。

改进:使用二叉查找树存储索引

1、二叉树

二叉查找树的特点:

        ①任何节点的左子树的键值,一定小于当前节点

        ②任何节点的右子树的键值,一定大于当前节点

二叉树的优点:

上述查找语句,经历两次io即可查到。

二叉查找树的规律:

        深度为1的,查找次数为1。深度为2的,查找次数为2。深度为n,查找次数为n。

上述二叉树平均查找次数:2.8次

二叉树的缺点:

在存储有序数据的时候,最终会形成一个链表,对于查找链表尾端的数据时,效率会很低。

2、平衡二叉树

既然二叉查找树不行,可以用平衡二叉树改进。

特点:

        ①在满足二叉查找树的条件下,还满足任意节点的两子树高度差最大为1。

优点:

        在出现大于1的情况下,会使用LL旋转,或者LR旋转进行平衡,最终满足条件。这样就不会出现链表的情况。

缺点:

        ①每个节点最多有两个子节点,导致树高度过高,io次数特别多

        ②每个节点只保存一个关键字,每次操作获取的目标数据过少

结合1,2可以总结出,想要提升数据库性能的关键:减少磁盘io

        ①节点可以有多颗子树

        ②每个节点尽可能多存储一些数据

由此引出B-Tree,(B是balance)

3、B-Tree树

1)什么是B-Tree

        B-Tree是一个多路平衡查找树,允许一个节点存放多个数据 。(把瘦高的树变成矮胖的树)

2)B-Tree树的阶

        B-Tree中所有节点的字数个数的最大值,称为B-Tree的阶。

上面这颗树所有节点,拥有子节点最多的节点有四个,都有三个子节点,所以上面这颗称为3阶B树。

3)m阶B-Tree满足以下条件:

        ①树的每个节点最多有m颗子树

        ②根节点至少有两颗子树(保持树的平衡)

        ③分支节点(除根节点,叶子节点外)至少有(m/2)颗子树。避免出现单颗子树的情况

        ④所有叶子节点都在同一层,并以升序排序

        ⑤有K颗子树的分支节点,则存在K-1个关键字,关键字按照递增顺序进行排序

4)B-Tree如何存储索引

        B树首先定义一条记录为一个键值对(key,value)

        ①key为记录的键值,对应表中的主键值

        ②value是除主键外的一行记录

5)B树存储索引的特点

        

B树存储数据的特点:

        ①空白的块是指针,存放着子节点的地址信息。

        ②每个节点都存储多个索引值以及对应的value值(value是除主键外的一行记录)。也就是说索引值和value数据分布在整棵树中

        ③树节点中的多个索引值从左到右升序排序

6)B-Tree查找方式的特点:

        ①每个节点的元素,可以视为一次io读取,树的高度就表示了最多的io次数

        ②每个节点存取的元素个数越多,B树越矮,查找需要的io次数就越小

7)总结

B树的优点:

        ①B树可以在内部节点存储键值和相关的记录数据,若是把频繁访问的节点放在根节点,可以提高热点数据的查询效率

B树的缺点:

        ①上述优点也可称为缺点。因为每个节点不仅包含key值,还有value值,当value值特别大的时候,就会导致每个节点存储的key值减少,这就会导致B树的层数变高,io变多。

B树的使用场景:

        主要应用于文件系统以及部分数据库索引,比如MongoDB。大多的关系型数据库都是使用B+Tree树结构进行管理索引。

聊B+Tree之前,我们先来讨论下B-Tree的不足,为什么mysql不用B-Tree管理索引。当然有一些前置的知识需要知道。

前置知识:

操作系统①操作系统从磁盘读取数据到内存是以磁盘块为基本单位的。

MYSQL②InnoDB存储引擎是按“页”来处理数据的,因此B-Tree/B+Tree的基础分配单位是页。InnoDB存储引擎中默认每个页的大小为16KB

show variables like 'innodb_page_size';

③磁盘块(block)实际上并没有这么大,因此InnoDB每次申请磁盘空间时都会是若干地址连续磁盘块来达到页的大小16KB

B-Tree的不足

①上述缺点,因为每个节点不仅包含key值,还有value值,如果每个节点都存储行数据是很占内存空间的,树的高度也变高,io也便多

②B树适用于随机访问,但是不适用于范围查询,因为范围查询通常需要顺序访问一系列的键值,不是随机访问。(究其原因是因为叶子节点不相连,顺序查询需要返回父节点,就像遍历整个树一样,io次数增特别多)

而B+Tree就是把B-tree的不足做了优化,更适合存储索引结构。

4、B+Tree

mysql的InnoDB存储引擎中,最小存储单元就是页(每个页默认大小是16KB)。而mysql的设计者将一颗B+Tree的节点大小就设置为了等于一个页(16KB),这样做的目的就是为了每个节点只需要一次io就能完整的载入一页数据。

mysql中B+Tree存储索引的特点:

        ①mysql除叶子节点外的节点的数据页,存放的是“关键字+指针“

        ②叶子节点的数据页,存放的是”关键字+数据“——单指聚簇索引

        ③B+Tree的根节点是保存在内存中的,子节点存储在磁盘中的。

        ④所有的节点按照索引键大小排序,构成一个双向链表,便于范围查询。

B+Tree的查找方式:

        ①和B-tree一样,从根节点通过指针实现随机查找,区别是B+Tree必须查找到叶子节点,才能获取到数据。

        ②到达叶子节点,可以进行顺序查找,在一个节点内部可以实现这般查找,在多个节点之间,因为是通过指针连接,所以要使用顺序查找。

例子:

随机查询就不举例了,和B-tree类似。

范围查询10~99的元素:

        ①自顶向下,查找到范围的下限10,通过链表的指针便利到元素99结束

我们发现对比B-tree的范围查询,B+tree的io次数更少,查询更简便。

B+Tree的优势:

  • B+Tree扫库和扫表能力更强。如果我们要根据索引去进行数据表的扫描,对B-Tree进行扫描,需要把整棵树遍历一遍,而B+TREE只需要遍历他的所有叶子节点即可(叶子节点之间有引用)。

  • B+Tree磁盘读写能力更强。他的根节点和支节点不保存数据区,所以根节点和支节点同样大小的情况下,保存的关键字要比B-Tree要多。所以,B+Tree读写一次磁盘加载的关键字比B-Tree更多。

  • B+Tree排序能力更强。上面的图中可以看出,B+Tree天然具有排序功能。B+Tree查询性能稳定。

  • B+Tree数据只保存在叶子节点,每次查询数据,查询IO次数一定是稳定的。当然这个每个人的理解都不同,因为在B-Tree如果根节点命中直接返回,确实效率更高。

一颗B+Tree可以存放多少数据:

首先一个高度2的B+Tree的记录数 = 根节点的指针数*单个叶子节点的记录数

1)根节点的指针书:int类型占4个字节,指针大小大概为6个字节

        一个页可以存储16KB/(4b+6b)约=1600,一个节点最多存储1600个索引指针

2)叶子节点的记录树:假设value1KB,一页可以存储16行数据,16KB/1KB=16

3)高度为2可以存放1600*16约3万条数据,高度为3的可以1600*1600*16=4千万条数据

B+Tree高度一般为1~3层,就可以满足千万级别的数据存储。

下面将写《MySQL是怎样运行的:从根儿上理解MySQL》(小孩子)的阅读笔记,感兴趣的可以关注一下。

  • 17
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 9
    评论
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值