所在的位置: mysql >> mysql市场 >> MySQLInnoDB索引原理

MySQLInnoDB索引原理

InnoDB是MySQL最常用的存储引擎,了解InnoDB存储引擎的索引对于日常工作有很大的益处,索引的存在便是为了加速数据库行记录的检索。以下是我对最近学习的知识的一些总结,以及对碰到的以及别人提到过的问题的一些分析,如有错误,请指正,我会及时更正。

目录

InnoDB表结构

B树与B+树

聚簇索引和二级索引

SQL执行顺序

SQL优化建议

一些问题分析

参考资料

1.InnoDB表结构

此小结与索引其实没有太多的关联,但是为了便于理解索引的内容,添加此小结作为铺垫知识。

1.1InnoDB逻辑存储结构

MySQL表中的所有数据被存储在一个空间内,称之为表空间,表空间内部又可以分为段(segment)、区(extent)、页(page)、行(row),逻辑结构如下图:

段(segment)

表空间是由不同的段组成的,常见的段有:数据段,索引段,回滚段等等,在MySQL中,数据是按照B+树来存储,因此数据即索引,因此数据段即为B+树的叶子节点,索引段为B+树的非叶子节点,回滚段用于存储undo日志,用于事务失败后数据回滚以及在事务未提交之前通过undo日志获取之前版本的数据,在InnoDB1.1版本之前一个InnoDB,只支持一个回滚段,支持个并发修改事务同时进行,在InnoDB1.2版本,将回滚段数量提高到了个,也就是说可以同时进行*个并发修改事务。

区(extent)

区是由连续页组成的空间,每个区的固定大小为1MB,为保证区中页的连续性,InnoDB会一次从磁盘中申请4~5个区,在默认不压缩的情况下,一个区可以容纳64个连续的页。但是在开始新建表的时候,空表的默认大小为96KB,是由于为了高效的利用磁盘空间,在开始插入数据时表会先利用32个页大小的碎片页来存储数据,当这些碎片使用完后,表大小才会按照MB倍数来增加。

页(page)

页是InnoDB存储引擎的最小管理单位,每页大小默认是16KB,从InnoDB1.2.x版本开始,可以利用innodb_page_size来改变页size,但是改变只能在初始化InnoDB实例前进行修改,之后便无法进行修改,除非mysqldump导出创建新库,常见的页类型有:数据页、undo页、系统页、事务数据页、插入缓冲位图页、插入缓冲空闲列表页、未压缩的二进制大对象页、压缩的二进制大对象页。

行(row)

行对应的是表中的行记录,每页存储最多的行记录也是有硬性规定的最多16KB/2-,即行(16KB是页大小,我也不明白为什么要这么算,据说是内核定义)

1.2InnoDB行记录格式

InnoDB提供了两种格式来存储行记录:Redundant格式、Compact格式、Dynamic格式、Compressed格式,Redudant格式是为了兼容保留的。

Redundant行格式(5.0版本之前的格式)

字段长度偏移列表:存储字段偏移量,与列字段顺序相反存放,若列长度小于字节,用一个字节表示,若大于字节,用两个字节表示记录头信息:固定用6字节表示,具体含义如下:

隐藏列:事务id和回滚列id,分别占用6、7字节,若此表没有主键,还会增加6字节的rowid列。

Compact行格式(5.6版本的默认行格式)

变长字段长度列表:此字段标识列字段的长度,与列字段顺序相反存放,若列长度小于字节,用一个字节表示,若大于字节,用两个字节表示,这也是MySQL的VARCHAR类型最大长度限制为NULL标志位:标识改列是否有空字段,有用1表示,否则为0,该标志位长度为ceil(N/8)(此处是MySQL技术内幕-InnoDB存储引擎与官方文档有出入的地方);记录头信息:固定用5字节表示,具体含义如下:

列数据:此行存储着列字段数据,Null是不占存储空间的;隐藏列:事务id和回滚列id,分别占用6、7字节,若此表没有主键,还会增加6字节的rowid列。

Note:关于行溢出,即Redundant格式、Compact格式存储很长的字符串,在该字段会存储该字符串的前个字节的前缀(字段超过字节则为变长字段),并将整个字符串存储在un


转载请注明:http://www.aierlanlan.com/rzdk/2022.html

  • 上一篇文章:
  •   
  • 下一篇文章: 没有了