首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

MySQL索引底层(一)索引底层原理

MySQL索引底层原理

局部性与页

在操作系统中,我们执行一个指令去磁盘取数据,那么他会从磁盘取出4KB数据,这个4KB就是一个局部单位,而这4KB数据就是你的指令中取出的数据周围的数据,因为操作系统认为你下一次的数据会从这条数据的周围中取。每次从磁盘读取数据在这里称为一次磁盘IO。那么在Mysql的操作当中,也有这么一个原理。

数据结构

现在我们有以上数据,当我们执行一句查询语句

代码语言:javascript
复制
select * from t_user where a = 3;

如果mysql没有局部性的概念的时候,那么这条sql会产生三次IO磁盘操作,则mysql会从磁盘取出第一条数据到内存中,然后比对a字段的值,一直比对到第三条才是正确的,那么会产生3次IO磁盘操作,有了局部性后,那么mysql会从磁盘中进行局部性的取出一页数据,这里一页数据是16KB,一次取出来后放到内存中,进行比对,那么就提高了执行效率。

页大小

代码语言:javascript
复制
show global status like 'Innodb_page_size';

通过上面的sql我们知道此时使用的Innodb存储引擎所对应的页大小是16384 也就是16384/1024 = 16KB。

页数据原理

当我们使用insert插入上面的语句的时候,其实可以看到插入的过程中,这4条数据已经按主键的顺序插入到MySQL中,那么在这个插入的过程是怎么样的,我们来研究一下InnoDB存储的过程。

首先插入第一条数据

接着我们插入第二条数据的时候,第二条数据的主键会跟第一条数据的主键比较大小,然后再插入。

最后插入的数据就会根据主键的大小来排序了

插入的数据就形成了我们页数据中的一部分--用户数据区域,并且每一条数据都有一个指针指向了下一条记录,这也形成了一个链表的形式,现在比如说我们要找a=3的数据,那么我们就得从第一条比对到第三条数据,然后取出,那如果有10000条数据呢?需要比对10000次。因为这是一个链表的数据结构,我们都知道链表的数据结构是增删快,查找慢,那么MySQL的InnoDB的存储引擎是怎么解决的呢,在这里引入了一个页目录

页目录在这里重新为主键排了一次序,比如一组的数据是2条,那么主键为1跟主键为2就为一组

如图,如果当我们要查找a=4的这一条数据,那么就从页目录中找,就可以立即找到该条数据会在第二组,然后在第二组中比对到了a=4之后,取出数据。这就是一页数据,那么当数据足够多,多到一页已经放不下了,自然就会有第二页。这里就引出一个页的指针。

接下来的页就会变成上面的数据结构,假设我们现在要找a=6的数据,那么就会基于第一页去找,发现第一页没有,那就基于第一页到第二页去找,发现在页目录5中,那么a=6就在页目录为5的组中取出数据,假如当页数达到了10000页呢,我们要找a=20000的数据,那就得一页一页的去比如页目录中的值,数据太多也很麻烦,现在就会有一个目录页的数据结构出来,也是同样的思路。

当我们要查找a=6的数据,在目录页中可以定位到在第100页的地址,那么我们就可以直接在第100页中去查找我们的数据。

最后渐渐的,就变成了一个B+树的数据结构。

下一篇
举报
领券