首页 > 社交 > 科普中国

MySQL索引原理篇:深入数据库底层揭开索引机制的神秘面纱

常驻编辑 科普中国 2022-10-08 索引   节点   字段   面纱   指针   底层   磁盘   机制   神秘   过程   类型   结构   数据库   引擎   数据
  • MyISAM非聚簇索引中,每个索引信息中则直接存储行数据的指针。
  • 当然,这里也是画出的伪结构,因为不可能按照MySQL单节点16KB的尺寸1:1还原,毕竟画不下这么大(实际MySQL对于上述这些数据,一个节点就全放下了)。dDi拜客生活常识网

    索引键的大小会随着值长度变化吗?

    这个问题很有趣,比如现在基于一个int类型的字段建立了一个索引,但目前的字段值是1,按理来说这个值只占1bits对不对?那在索引键中,或数据库中占多少呢?答案是4Bytes/32bits,这是因为一个int类型在操作系统中就会占用32bit空间,不会根据实际值而减少占用空间。dDi拜客生活常识网

    但大家也都知道,数据库中还有不少文本类型,例如varchar类型,它是固定的长度吗?并不是,它是一个变长类型,而非一个定长类型,也就是一个varchar字段值,占用的空间会随着实际所存储的数据而变化。dDi拜客生活常识网

    所以对于一个索引键的大小是否会发生变化,这要取决于你是基于什么字段类型建立的索引,如果是定长类型就不会变化,但如果是变长类型就会随之发生改变。dDi拜客生活常识网

    三、索引内部查询与维护的过程

    建立索引时会发生的内部过程,上一段落已经阐述明白了,接着再来说说查询SQL执行时,如果选中了索引,索引内部的检索过程是什么样的呢?也包括当写类型的SQL更改表中数据后,MySQL又会如何维护索引的内部结构呢?dDi拜客生活常识网

    3.1、聚簇索引查找数据的过程

    在《SQL执行篇》中聊到过,当查询SQL来到MySQL后,经过一系列处理后,最终会来到优化器,此时会由优化器来为SQL语句选择出一个合适的索引,当然,你也可以手动强制指定索引。那当SQL命中索引时,索引内部是如何查找对应的行数据的?dDi拜客生活常识网

    工作线程执行查询SQL时,首先会先看一下当前索引的结构,如果是Hash索引就很简单了,直接对索引字段的值进行哈希计算,然后直接根据哈希值,从索引中找到相应的索引信息,最后获取数据即可。dDi拜客生活常识网

    但如果索引结构是默认的B+Tree呢?内部又会发生什么工作?dDi拜客生活常识网

    如果当前SQL使用的是主键/聚簇索引,比如:dDi拜客生活常识网

    SELECT * FROM `zz_user` WHERE `ID` = 12;
    复制代码

    此时首先会根据条件字段,去内存中找到聚簇索引的根节点,然后根据节点中记录的地址去找次级的叶节点,最后再根据叶节点中的指针地址,找到最下面的叶子节点,从而获取其中的行数据,动画过程如下:dDi拜客生活常识网

    dDi拜客生活常识网

    B+Tree结构的索引似乎查找过程也并不复杂对不对?但有一个细节点需要注意,B+Tree的单个节点可存储多个数据,也就是当磁盘IO发生后,MySQL一次读取的数据中有多个索引信息,此时MySQL会如果查找单个节点中的索引信息呢?全部判断一次嘛?dDi拜客生活常识网

    其实并不会全部判断一次,因为B+Tree是一种有序的数据结构,小的会放左边,大的会放右边,单个节点中的索引信息,同样遵循这个原理。既然单个节点中的数据也是有序的,所以MySQL同样会采用二分查找法去检索数据。对于单个节点中的索引信息,先从索引中间开始查询,然后判断一下当前SQL中ID=12这个条件,是大于还是小于最中间的索引键,小于则去节点左边取中间的索引键继续判断,大于则去右边.....,以此类推直至定位到单节点中对应索引键为止。dDi拜客生活常识网

    OK,如果是范围取值,比如取ID>=2的所有数据,则会先定位到ID=2的索引键,然后通过叶子节点之后的指针,直接将2之后的数据全部取出。dDi拜客生活常识网

    聚簇索引中,定位到了索引键,即代表着取到了数据,毕竟索引和行数据是一起存储的。dDi拜客生活常识网

    3.2、非聚簇索引查找数据的过程

    相较于聚簇索引而言,非聚簇索引前面的步骤都是相同的,仅是最后一步有些许不同罢了,非聚簇索引经过一系列查询步骤后,最终会取到一个聚簇索引的字段值,然后再做一次回表查询,也就是再去聚簇索引中查一次才能取到数据。

    相关阅读:

  • 如何建立索引(数据库中表属性的默认值)
  • 如何建索引(界面方式创建索引)
  • word目录怎么做索引,word文档怎么做索引目录
  • POI导入导出百万级数据Excel
  • MySQL专题1:
  • MongoDB高并发下的upsert问题
  • 面渣逆袭:MySQL六十六问,两万字+五十图详解!有点六
  • MySQL
  • 索引和目录的区别是什么
  • lucene学习
    • 网站地图 |
    • 声明:登载此文出于传递更多信息之目的,并不意味着赞同其观点或证实其描述。文章内容仅供参考,不做权威认证,如若验证其真实性,请咨询相关权威专业人士。