那么说到这里,其实可以回答第一个问题了,MySQL实际上就是在我们插入数据的时候,就帮我们在页中排好了序,至于为什么要排序,这里先卖个关子,接着往下看 。
排序对性能的影响上文中我们提了一个问题,为什么数据库在插入数据时要对其进行排序呢?我们按正常顺序插入数据不是也挺好的吗?
这就要涉及到一个数据库查询流程的问题了,无论如何,我们是绝对不会去平白无故地在插入数据时增加一个操作来让流程复杂化的,所以插入数据时排序一定有其目的,就是优化查询的效率 。
而我们不难看出,页内部存放数据的模块,实质上就是一个链表的结构,链表的特点也就是增删快,查询慢,所以优化查询的效率是必须的 。
基于单页模式存储的查询流程还是基于我们第一节中的那张页图来谈,我们插入了五条数据,id分别是从1-5,那么假设我要找一个表中不存在的id,假设id=-1,那么现在的查询流程就是:
将id=1的这一整页数据取出,进行逐个比对,那么当我们找到id=1的这条数据时,发现这个id大于我们所需要找的哪个id,由于数据库在插入数据时,已经进行过排序了,那么在id=1的数据后面,都是id>1的数据,所以我们就不需要再继续往下寻找了 。如果在插入时没有进行排序,那毋庸置疑,我们需要再继续往下进行寻找,逐条查找直到到结尾也没有找到这条数据,才能返回不存在这条数据 。
当然,这只是排序优化的冰山一角,接着往下看 。
上述页模式可能带来的问题说完了排序,下面就来分析一下我们在第一节中的那幅图,对于大数据量下有什么弊端,或者换一个说法,我们可以怎么对这个模式进行优化 。
我们不难看出,在现阶段我们了解的页模式中,只有一个功能,就是在查询某条数据的时候直接将一整页的数据加载到内存中,以减少硬盘IO次数,从而提高性能 。
但是,我们也可以看到,现在的页模式内部,实际上是采用了链表的结构,前一条数据指向后一条数据,本质上还是通过数据的逐条比较来取出特定的数据 。
那么假设,我们这一页中有一百万条数据,我们要查的数据正好在最后一个,那么我们是不是一定要从前往后找到这一条数据呢?
如果是这样,我们需要查找的次数就达到了一百万次,即使是在内存中查找,这个效率也是不高的 。那么,有什么办法来优化这种情况下的查找效率呢?
页目录的引入我们可以打个比方,我们在看书的时候,如果要找到某一节,而这一节我们并不知道在哪一页,我们是不是就要从前往后,一节一节地去寻找我们需要的内容的页码呢?
答案是否定的,因为在书的前面,存在目录,它会告诉你这一节在哪一页,例如,第一节在第1页、第二节在第13页 。在数据库的页中,实际上也使用了这种目录的结构,这就是页目录 。
那么引入页目录之后,我们所理解的页结构,就变成了这样:

文章插图
分析一下这张图,实际上页目录就像是我们在看书的时候书本的目录一样,目录项1就相当于第一节,目录项2就相当于第二节,而每一条数据就相当于书本的每一页
这张图就可以解释成,第一节从第一页开始,第二节从第三页开始,而实际上,每个目录项会存放自己这个目录项当中最小的id,也就是说,目录项1中会存放1,而目录项2会存放3 。
那么对比一下数据库在没有页目录时候的查找流程,假设要查找id=3的数据,在没有页目录的情况下,需要查找id=1、id=2、id=3,三次才能找到该数据,而如果有页目录之后,只需要先查看一下id=3存在于哪个目录项下,然后直接通过目录项进行数据的查找即可
如果在该目录项下没有找到这条数据,那么就可以直接确定这条数据不存在,这样就大大提升了数据库的查找效率,但是这种页目录的实现,首先就需要基于数据是在已经进行过排序的的场景下,才可以发挥其作用,所以看到这里,大家应该明白第二个问题了,为什么数据库在插入时会进行排序,这才是真正发挥排序的作用的地方 。
页的扩展在上文中,我们基本上说明白了MySQL数据库中页的概念,以及它是如何基于页来减少磁盘IO次数的,以及排序是如何优化查询的效率的 。
那么我们现在再来思考第三个问题:在开头说页的概念的时候,我们有说过,MySQL中每一页的大小只有16KB,不会随着数据的插入而自动扩容,所以这16KB不可能存下我们所有的数据,那么必定会有多个页来存储数据,那么在多页的情况下,MySQL中又是怎么组织这些页的呢?
推荐阅读
- MySQL读写分离?MySQL主从复制原理?如何解决主从同步延时?
- 小黄单车创始人 共享单车巨头
- 坐便器飞小虫子怎么处理,马桶飞虫从哪里出来的
- 梦见水从地下往上冒成了一个池塘 梦见水从地下往上冒,地裂缝
- 闻香识台茶
- 肖光亮,从门外汉到制茶能手
- 梦见车子从很高掉下去醒来心跳很快吓死了 梦见车子从很高掉下去,粉身碎骨
- 郑来荣,昔日庄稼汉 今朝茶老板
- 梦见用担架抬死人,突然人活了 梦见用担架抬死人从我身边路过
- 秋季润燥保健茶方DIY推荐
