美文网首页
InnoDB索引查询原理

InnoDB索引查询原理

作者: Franck_ | 来源:发表于2020-10-28 10:37 被阅读0次

1 没有所有是如何查询数据的?

如果没有建立索引的话,执行查询的时候,会将硬盘里面的数据页,加载进去buffer pool,然后遍历查找,查找完后,再去加载新的数据页,一直到遍历完所有的数据页,这样效率是非常低的。时间复杂度是O(n)。

2 索引的基础概念。

数据在数据页里面的存储是按照主键从小到大排列的,数据页内的数据行通过单向链表链接在一起。如下图所示:


数据页结构

这时候,我们查数据的话,是不知道我们的目标数据是在哪个数据页里面的。例如要找id = 5的这条数据。 是不知道这条数据是在数据页1还是在数据页2的。这时候我们需要一个东西来标记提示,每个数据页里面存在什么数据。 例如:


页目录

这个结构叫做页目录,其实是和数据页放在一起的,是数据页的一部分。页目录还记录着对应主键的数据,存在于数据页的物理位置。

那这时候我们去页目录里面找id=5的数据,是怎么找的呢?由于页目录还是放在数据页里面,所以还是需要将数据页加载到buffer pool再进行查找。将数据页1加载到buffer pool,然后找数据页的页目录,发现id最小=1, 最大=3 ,发现不在本数据页内。

继续加载下一个数据页2 , 然后查找页目录,id最大=4,最小=6,数据在这个数据页的范围内, 然后继续进行二分查找,直到找到id=5这个数据目录,然后根据这个目录给出的id=5这条数据的物理地址,获取到这条数据。

这时候,虽然不用在数据页里面一条一条遍历查找了,但是还是需要不断加载数据页到buffer pool进行查找,时间复杂度还是O(n)。

可以考虑将页目录抽取出来,独立做成一个数据结构,独立于数据页,这样就不用加载数据页进buffer pool就可以用页目录进行查找了。抽取出来的页目录暂时叫做主键目录,抽出页目录出来的时候,进行一下优化,不需要将每个目录的所有id都列出来,只需要将最小的id列出就可以了,这样也可以确定id大小的范围。如下图:

主键目录

这时候,我们需要查找主键id=5的数据的过程,对比主键目录的第一条记录和第二条记录,id是否大于等于1小于4,否。那么就id=5这条数据是在第二条记录里面的,因为主键目录只有2条记录。根据主键目录,就可以确认数据是在数据页2里面。这时候,加载数据页2到buffer pool。然后对数据页2的页目录进行二分查找,找到id=5这条数据的位置,然后获取id=5这条数据,

这个主键目录,可以叫做索引,是一个基础的一个概念,但不是真正的完整的InnoDB的索引。

3 InnoDB索引的基础结构

随着数据越来越多,索引条目(一条最小id和数据页对应的记录)也会越来越多,不可能将所有的索引条路放在一个索引目录里面,所以需要分开存储。当索引目录一分为二的时候,我们就可以将这两个索引目录称为索引页,和数据页同一个道理。如下图:

索引页

按照当前这样的索引页切分方式的话,查询效率也会很低的。先加载索引页1到内存,然后用二分查找,如果没有找到再加载索引页2到内存,进行二分查找。如此往复,一直到查找数据。 最坏情况下,就要将所有的索引页都找一遍,也就是遍历了。时间复杂度又变成O(n)了。

在数据有序的情况下,进行查找,使用树结构,效率会得到非常大的提升。如下图所示:


树状索引

这时候,如果要查id=5这条数据:加载索引页1 ,然后发现id最小的索引条目是10,比5大,所以去索引页的左子树索引页2里面找,二分查找发现id=5这条数据在最后一个条目,在数据页2,然后就去数据页2里面进行二分查找,获取到id=5这条数据。这样,数据页3就永远不会加载,大大提升了查询效率。

如果采用这样的结构,就会容易造成树的层级过多,降低查找的效率。 例如,每个数据页只能存10个索引条目,索引页1存了10条索引目录,分别是1-10。那么再增加10个索引条目的时候,就只能再增加一个索引页2(索引条目是11-20),索引页2只能做索引页1的右子树,这时候,再增加一个索引页3(索引条目是21-30),那么索引页3就只能作为索引页2的右子树。当前树就有了3层。每个索引页的数据范围只能是10个,降低了二分查找范围。

这时候,如果要找id=25的数据,就需要先到索引页1,进行二分查找,因为25比10大,所以去索引页2里二分查找,发现还是比20大,再去索引页3里面二分查找,最后在索引页3里面找到。 这样就经理了3次二分查找。

可以再进行一层抽象:树的叶子节点,才实际存储索引条目,其他节点,只存储子节点的最小id,和子节点的指向。如图:

索引结构

如果按照这样的数据结构来进行存储,查找的效率就大大提升了。 例如现在要找id=95的数据。 那么,只需要加载索引页1 , 然后二分查找,发现95大于60。所以数据在索引页4,然后去索引页4里面进行二分查找,就可以找到id=95的数据,然后找到对应的数据页6 。 然后再去数据页6的数据目录上进行二分查找,找到id=95对应的数据所在的物理位置。

这样的结构,就可以增大每次二分查找的数据范围,减少二分查找的次数。提升二分查找的效率。

到此,索引的结构就如上图所示,这个就是一个概念上的索引的结构了。

相关文章

  • 索引

    MySQL索引原理及慢查询优化 索引的储存分类: BTREE索引和HASH索引。MyISAM 和 InnoDB 存...

  • InnoDB索引查询原理

    1 没有所有是如何查询数据的? 如果没有建立索引的话,执行查询的时候,会将硬盘里面的数据页,加载进去buffer ...

  • 2019-03-18

    mysql innodb索引原理 聚簇索引 聚集索引就是按照每张表的主键顺序构造一颗B+树。 查询优化器倾向于采用...

  • MySQL中的回表查询与索引覆盖

    了解一下MySQL中的回表查询与索引覆盖。 回表查询 要说回表查询,先要从InnoDB的索引实现说起。InnoDB...

  • Mysql进阶知识总结

    0-索引 索引原理与优化 0.1- MyISAM/InnoDB索引原理(聚集索引、非聚集索引) 索引是在存储引擎层...

  • Mysql聚簇索引

    存储引擎InnoDB索引是一种数据结构(本质是对数据排序),能提高我们的查询速度:运用 局部性原理 索引采用的数据...

  • mysql 索引结构图解

    摘要: 本篇介绍下Mysql的InnoDB索引相关知识,从各种树到索引原理到存储的细节。 InnoDB是Mysql...

  • Innodb索引原理

    基本概念 数据库的索引类似书的目录,我们通过标题及其对应的页码便可快速的找到标题对应的内容。在数据库中,可以根据索...

  • InnoDB索引原理

    1. InnoDB中Page结构 在InnoDB中,Page是整个InnoDB存储的最基本构件,也是InnoDB磁...

  • 高级8、数据库索引之覆盖索引coveringindex

    简介 覆盖索引是InnoDB中索引的特例,索引中包含查询的所有必填字段;换句话说,索引本身包含执行查询所需的数据,...

网友评论

      本文标题:InnoDB索引查询原理

      本文链接:https://www.haomeiwen.com/subject/gflxvktx.html