Mysql索引

Mysql索引之B-Tree和B+Tree

B-Tree

首先我们来看,B-tree这种数据结构是怎么样的,请看下图:

B-Tree
B-tree实际上可以说是多叉平衡树,它的局部明显也符合二叉树的特性,B-Tree通过在每个节点进行一个"横向的扩展",让这种数据结构及时在数据量很庞大的时候,也能控制Tree的高度!观察一下它的每一个节点,看出它实际上是由两部分组成,一个是索引值,一个是data
那么这个data我们可以简单的理解,它是存储了这个索引值所在的那行数据的对应的磁盘文件地址指针!或者是除了索引所在那行的除了索引字段的其他字段的数据集合!(这里就涉及到一个聚簇索引和非聚簇索引的概念)等会来说

其次我们来看一个完整的通过B-Tree这种数据结构来查询数据的一个过程

首先呢,先从根节点开始查,一般来说,会事先把根节点load到内存中,然后呢在内存中进行比对,比如说找的是23那行数据,开始比对,发现23>15,然后往右进行比对,发现23<60,那么就定位到15的右边的第一个子节点(因为二叉树的一个特性),此时会把这个子节点load到内存中,然后在内存中进行比对,开始比对,发现23>20那么此时就定位到右边的子节点,同样的操作,直至定位到索引值为23的那个节点,并根据那个节点上的data里面保存的磁盘文件地址指针拿到需要的那行数据…

B+Tree

首先我们来看一下B+Tree这种数据结构是啥样的?

基于myisam引擎的B+Tree

myisam-B+Tree

基于innodb引擎的B+Tree

在这里插入图片描述
仔细观察一下,很容易发现,这两种存储引擎下面的B+Tree这种数据结构在叶子节点有很明确的区别;

  • MyIsAm中B+Tree的叶子节点只存储了索引数据和索引所在行的磁盘文件地址指针
  • Innodb中B+Tree的叶子节点不仅存储了索引数据,并且还存储了索引所在行的所有其他字段的数据
    那么这里会引出一个概念----聚簇索引
    其实聚簇索引可以用一句话来描述:叶子节点保存了完整的数据或作索引数据和字段数据放在了一块!

再来说说这两种存储引擎的数据存储区别:
表
如上图,userinfo是基于innodb存储引擎的表, 有两种类型的文件,一种是frm,一种是ibd文件

  • frm文件是存储表结构定义的数据
  • ibd文件实际上表数据,并且是基于B+Tree这种数据结构组织的索引结构文件,也就是表数据和索引数据放在了一块,并且用了B+Tree这种数据结构来组织在一起

显然client就是基于myisam存储引擎的表,有三种类型的文件,一种是frm,一种是MYD,还有一种是MYI

  • frm文件是存储表结构定义的数据
  • MYD文件是存储表数据
  • MYI文件是存储索引数据
    显然myisam存储引擎的索引是非聚簇索引,innodb的则是聚簇索引

它的查询数据的过程与B-Tree一致,可以参照上文

对比B-Tree和B+Tree这两种数据结构!不难发现他们之间的区别

可以说B+Tree是B-Tree的一个变种,B+Tree是在B-Tree的基础上做的一个优化的产物;
通过上图我们可以看到有一下几个明显的区别

  • B-Tree中的每个索引节点存放了索引值+data(索引所在行的磁盘文件地址指针),而B+Tree则弃用了这种存储方式,在非叶子节点中,每个索引节点只有索引值,这样一来每个非叶子节点可以存储更多的索引节点,提升了横向扩展的效果!并且B+Tree中,它的索引数据在每个叶子节点上面做了冗余,也就是说在每个非叶子节点上面的索引数据在叶子节点有一份完整的备份;
  • B+Tree的叶子节点中的索引节点用指针连接,并且维护的数据特点是从左往右是增长的,当然这就是二叉树的特性,a<b<c,那么自然有a<c;那么为什么要维护这种数据呢,就是为了让B+Tree更好的支持范围查询;
    试想一下,如果没有指针连接,那么当你进行范围查询的时候,假设是这么一条sql语句,id是索引,并且是bigint类型,自增的状态;select user_name,pass_word from user_info where id > 15那么会是什么情况?
    会是这样的情况,先从根节点开始比对,发现大于15应该走右边子节点,然后到了第二层的节点,同理也是刚好走15的右边,但是到了叶子节点,发现大于15的要走右边,找到了18.然后呢?然后是不是就又得从当前节点的上一层也就是父节点开始比对?但是如果我们加了指针连接呢?指针一口气给你往右遍历,拿到所有的id>15的你需要的数据,这不就极大的缩短了时间吗?Hash这种数据结构致命的缺陷也是在这里,所以我们不得不佩服,B+Tree这种这么优秀的数据结构的设计者!!实在是太厉害了!当然人家肯定也是经过很长时间的沉淀,很长的时间的不断学习才会有这种产物!!在这里,想给点鸡汤,作为一个程序员,不持续不断的学习和总结,是对自己极大的不负责任,我们一定要给自己在职业生涯的起点就规划好自己的学习路线!选择能帮助你成长的领导也是非常重要!!!

B+Tree实在是非常优秀,它的出现让我们在千万数据中查询某一行数据都不再是噩梦!
那么我们就来具体说说,它究竟是怎么做到的!

  • 先来看看每个节点的默认大小
    在这里插入图片描述
    我们可以看到每个节点的默认大小是16384字节,也就是16kb;
    一般情况下,我们的索引值选为bigint型;最大的一个好处是便于比较,并且在自增的情况下,B+Tree对索引的范围查询支持非常不错!!!后续会来解释为什么这样选择!
  • bigint类型的数据占8个字节,指针的大小一般也为4或8个字节,那我们先姑且算是8个字节,那么也就是一个非叶子节点大小一共是16个字节,那么我们可以算一下,一个节点能存放多少个这样的叶子节点:16384/16=1024(个),那么我们再来看,当树的高度为3的时候,叶子节点大概能存下多少索引:那么假设一个叶子节点中的索引值+data所占大小为1kb,那么一个叶子节点可以放16个这样的索引,那么我们来计算一下,也就是1024102416=1600多万个索引,也就是说当这颗B+Tree被撑满的情况下,叶子节点可以存放1600多万的索引个数,我们可能恍然大悟,其实这就是B+Tree能支持千万级数据量的快速查询的原因所在!
MySQL索引是一种数据结构,可以帮助MySQL快速定位和访问表中的数据。使用索引可以提高查询效率,降低数据库的负载。下面是MySQL索引的一些基本概念和使用方法: 1. 索引类型 MySQL支持多种类型的索引,包括B树索引、哈希索引、全文索引等。其中,B树索引是最常用的一种,也是默认的索引类型。B树索引可以用于精确匹配和范围查询,而哈希索引主要用于等值查询,全文索引则用于文本检索。 2. 索引创建 可以在创建表时指定索引,例如: ``` CREATE TABLE users ( id INT PRIMARY KEY, name VARCHAR(50), email VARCHAR(50), INDEX idx_email (email) ); ``` 也可以在已有的表上添加索引,例如: ``` ALTER TABLE users ADD INDEX idx_name (name); ``` 3. 索引使用 查询语句中可以使用WHERE子句和ORDER BY子句来利用索引,例如: ``` SELECT * FROM users WHERE email = 'example@example.com'; SELECT * FROM users WHERE name LIKE 'John%' ORDER BY id DESC; ``` 需要注意的是,索引并不是越多越好,过多的索引会占用过多的磁盘空间并降低写操作的性能。因此,需要根据实际情况选择合适的索引。同时,还需要定期对索引进行维护,包括优化查询语句、删除不必要的索引等。 4. 索引优化 MySQL提供了一些工具来优化索引,例如EXPLAIN命令可以帮助分析查询语句的执行计划,找出慢查询和不必要的全表扫描。可以使用OPTIMIZE TABLE命令来优化表的索引和碎片,从而提高查询性能。还可以使用缓存来避免频繁的查询操作,例如使用Memcached或Redis等缓存工具。 以上就是MySQL索引的一些基本概念和使用方法,需要根据实际情况进行选择和优化。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值