首页 > 社交 > 科普中国

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

常驻编辑 科普中国 2022-10-08 索引   节点   字段   面纱   指针   底层   磁盘   机制   神秘   过程   类型   结构   数据库   引擎   数据
dDi拜客生活常识网

上述这个过程,是表数据为空时,创建索引会干的工作,还算比较简单,但当表中有数据时,过程也一样吗?NO,会多出很多步骤。dDi拜客生活常识网

当表中有数据时,首先MySQL-Server会先看一下目前要创建什么类型的索引,然后基于索引的类型对索引字段的值,进行相应的处理,比如:dDi拜客生活常识网

  • 唯一索引:判断索引字段的每个值是否存在重复值,如果有则抛出错误码和信息。
  • 主键索引:判断主键字段的每个值是否重复、是否有空值,有则抛出错误信息。
  • 全文索引:判断索引字段的数据类型是否为文本,对索引字段的值进行分词处理。
  • 前缀索引:对于索引字段的值进行截取工作,选用指定范围的值作为索引键。
  • 联合索引:对于组成联合索引的多个列进行值拼接,组成多列索引键。
  • ........

根据索引类型做了相应处理后,紧接着会再看一下当前索引的数据结构是什么?是B+Tree、Hash亦或是其他结构,然后根据数据结构对索引字段的值进行再次处理,如:dDi拜客生活常识网

  • B+Tree:对索引字段的值进行排序,按照顺序组成B+树结构。
  • Hash:对索引字段的值进行哈希计算,处理相应的哈希冲突,方便后续查找。
  • .......

到这一步为止,已经根据索引结构,对索引字段的值处理好了,此时就会准备将内存中处理好的字段数据,写入到本地相应的磁盘文件中,但如果此时为InnoDB引擎,那在写入前还会做最后一个判断,也就是判断当前的索引是否为主键/聚簇索引:dDi拜客生活常识网

  • 如果当前创建索引的字段是主键字段,则在写入时重构.ibd文件中的数据,将索引键和行数据调整到一块区域中存储。

当然,如果这里创建的不是主键/聚簇索引,或者目前是MyISAM引擎,则意味着现在需要创建的是非聚簇索引,因此会先会为每个索引键(索引字段值)寻找相应的行数据,找到之后与索引键关联起来,不过InnoDB、MyISAM引擎两者之间的非聚簇索引也会存在些许差异,所以在这里也会有一点点不同:dDi拜客生活常识网

  • InnoDB:因为有聚簇索引存在,所以非聚簇索引在与行数据建立关联时,存放的是主键/聚簇索引的字段值。
  • MyISAM:由于表数据在单独的.MYD文件中,因此可以直接以指针的形式关联起来。

也就是说,InnoDB引擎中的非聚簇索引,都是主键/聚簇索引的“附庸”,因此每个索引信息中是以「索引键:聚簇字段值」这种形式关联的。dDi拜客生活常识网

但MyISAM引擎中由于表数据和索引数据都是分开存储的,所以MyISAM的每个非聚簇索引都是独立的,因此每个索引信息则是以「索引键:行数据的地址指针」这种形式关联。dDi拜客生活常识网

由于MyISAM引擎的非聚簇索引,关联的是行数据的指针,而InnoDB引擎关联的是聚簇索引的索引键,所以InnoDB的非聚簇索引在查询时需要回表,再查一次聚簇索引才能得到数据。而MyISAM每个非聚簇索引都能直接获取到行数据的地址,可以直接根据指针获取数据,从整体而言,MyISAM检索数据的效率会比InnoDB快上不少。dDi拜客生活常识网

到这里,索引键和行数据关联好之后,就会开始根据引擎的不同,将内存中的索引信息分别写入到不同的磁盘文件中。写完完成后,B+Tree的根节点会放到内存中维护,以便于后续索引查询时再次从磁盘读取根节点信息。dDi拜客生活常识网

到这里为止,大家也应该明白了为什么创建表之后,立马建索引会很快,但当表中有不少数据时创建索引会很慢的原因,就是因为表中有数据时,创建索引要做一系列判断、处理工作。dDi拜客生活常识网

OK~,最后再放上一个聚簇索引和非聚簇索引的结构区别:dDi拜客生活常识网

dDi拜客生活常识网


在上图中给出了一张用户表,然后基于ID字段建立主键/聚簇索引,基于name字段建立普通/非聚簇索引,最终索引结构如图中所示。dDi拜客生活常识网

  • 在InnoDB聚簇索引的示意图中,由于不方便画出每行数据,就用row_data代替行数据。
  • 在InnoDB非聚簇索引中,每个索引信息中存储聚簇索引的ID值。

相关阅读:

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