深入理解索引

本文详细解释了B+树作为索引底层结构的原因,对比了B+树与红黑树的优缺点,特别强调了在没有创建主键时隐藏索引的作用以及索引命中的不同情况对查询效率的影响。
摘要由CSDN通过智能技术生成

基础框架:

要想深入理解索引,我们首先要先弄清楚索引的底层结构,它的底层其实是一个B+树,B+树是什么呢?它是一个特殊的树,当然它也不像二叉树那么特殊,具体它的结构如下图:在这里插入图片描述
如上图所示,我们可以看到每一个子节点都重复继承了父亲节点的一个最大的数据,按照这个规律一直延伸到叶子节点,直到叶子结点的最后其实还有很多歩奏,这里我就不赘述了。按照这样分叉:最后一行的叶子结点就能对应所有的数据。我们此时将每个数据都逐个插入到叶子节点就行了。
在这里插入图片描述
而对于其他的非叶子节点,只需要将按照主键创建的索引列的key值存进去就行了(这里的 key 你可能会不明白,可以先看一看上图;也不一定只按照主键创建索引,还可能有按照其他创建的索引,段尾都有解析 ),而不用将那一整行都存进去,这样我们就能节省非叶子节点所占用的内存,因此,我们就可以将非叶子节点直接加载到内存中去进行查找,这样能大大提高查找的效率,这也是红黑树所不具备的。
既然我们说到了B+树和红黑树,那我们就详细谈谈为什么B+树能成为管理数据的底层,而二叉搜索树:红黑树却不行。

优缺点:

红黑树的劣势

  • 由于一行中所有的数据都储存在节点中,数据量庞大,所以他只能储存在硬盘中,这样每次遍历搜索树都要对硬盘 IO 进行访问,这样的速度是很慢的,因此红黑树不适合大规模管理硬盘上的数据。
  • 红黑树是二叉搜索树,当数据量非常大的时候,树的高度就变的非常高,查询的效率就会非常低。
    B+树的优势
  • 由于所有的非叶子节点都只储存了一个key ,占用的内存较小,因此我们可以直接将那部分非叶子节点直接加载到内存中去,但是到底什么时候加载,那就要看MySQL 源码了。要知道直接在内存中的运行速度可比多次访问硬盘要快多了,况且B+树只需要访问一次,这唯一的一次就是最终访问叶子节点里的数据的时候进行的。这样就提高了效率。
  • 每个节点上的key也是有序排列的,因此我们可以利用二分查找。
  • B+树也会控制每个节点上保存的key不会太多,如果插入的数据使key变多了,它的节点还是会分裂出更多的子树出来。
    上述解析
    这里的key 其实是我画的方框里的值,有几个值就有几个key,上述我们采取了,每次都保存最大值,当然也有其他的方式,但是继承父亲节点的值这样的思想是不变的。这里的key值也是你所创建的那个索引列那一列所储存的值,如上图。所以key可以指任何东西,比如:name,ID,class………只要它被包含在这个索引列中。
    说完上面,我们就自然引出了第二个问题:为什么不一定只按照主键创建的索引:因为我们在创建表的时候不一定每次都会创建主键吧,这就引出了,我们接下来要说的隐藏主键,什么是隐藏索引呢?就是当我们没有主动创建主键的时候,MySQL 就不能自动帮我们创建一个主键索引了。但是,它就不创建索引了吗?不不不,他还是会出手的,它就会默认一列,再次创建一个普通索引,这个索引是隐藏的,所以我们就不能使用sql 来使用它了。因此,我们此时就不能使用索引来加快速度了,只能一个个的遍历了,当然我们也不会是按照B+树的节点一个个的遍历,此时那个由叶子节点所连成的链表就发挥作用了,我们就能利用这个链表来进行一个个遍历,这样又进一步提高了效率。

对“索引的命中”的理解

理解:“对于这个索引的命中”,
情况一:我们创建了主键,MySQL会按照这个主键来自动创建一个索引,该索引的叶子结点存储了某对应行的对应索引列的数据,假如我们此时直接再创建一个索引的话,虽然也会创建成功。但是,不推荐。因为,此时MySQL已经给我们创建好了一个主键索引,那我们为什么还要费力再去创建一个呢?,创建成功的效果如下:在这里插入图片描述
那此时,如果我们创建一个普通索引的话,该普通索引的叶子结点储存的数据其实是我们主键索引的一个指针(目前可以理解成一个指向主键索引的一个指针),在查询的时候,假如你使用的是普通索引(即:你命中了普通索引),他会先使用普通索引找到普通索引的叶子结点,然后根据该叶子节点,找到主键的位置,然后再在主键的索引里找到的叶子节点,此时找到的叶子结点储存的数据才是,真正的表里的数据,我们也将这样的进行二次查找的叫做 “回表”。
但是如果我们在一开始就没有创建主键,MySQL会默认一列,默认帮我们生成一个索引,只是这个索引是隐藏的,我们无法在sql语句中使用它。因此我们在进行直接查询的时候是使用不了索引的,因此,此时只能直接遍历这个表,而由于表的内部结构是一颗B+树,因此我们只需要遍历那些由链式结构连接起来的叶子节点即可,这样也大大提高了效率。
但是如果我们此时创建了一个普通索引呢?此时会默认一列,MySQL为我们创建一个隐藏索引,这个隐藏的索引和上诉的隐藏主键是差不多的。然后,当然还是按照普通索引来进行查询了,然后进行回表操作就行了。
但是,如果我们什么索引都没有创建的时候,此时隐藏的索引我们是不能用的,此时就直接是遍历链表了,(即:没有命中索引)。
综上所述:
主要的关系就是:
在这里插入图片描述

以上就是关于索引的所有内容,感谢您的观看。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值