为什么别人能用好 MySQL?万字详解其复杂原理( 六 )

索引结构InnoDB数据文件本身就是索引文件,其索引分聚集索引和辅助索引,聚集索引的叶节点包含了完整的数据记录,辅助索引叶节点数据部分是主键的值,除了空间索引外,InnoDB的索引实现基本都是 B+ 树,如图所示 。
其中非叶子结点存储的是子页的最小的键值和子页的页号,叶子结点存储的是数据,数据按照索引键排序 。同一层的页之间用双向链表连接(前面提到的FIL Header中PREV PAGE 和 NEXT PAGE),同一页内的记录用单向链表连接(Record Header中记录了下一条记录的偏移) 。每一页设置了两个虚拟记录Infimum和Supremum用于标识页的开始和结束 。

为什么别人能用好 MySQL?万字详解其复杂原理

文章插图
 
索引结构
在InnoDB中根据辅助索引查询,如果除了主键外还有其他字段,则需要查询两遍,先根据辅助索引查询主键的值,然后再到主索引中查询得到记录 。此外,因为辅助索引的数据部分是主键值,主键不能过大,否则会导致辅助索引占用空间变大,用自增ID做主键是个不错的选择 。
mysql> create table t2(id int auto_increment primary key, ch varchar(10), key(ch));mysql> insert into t2(ch) values('ab');创建一个新的测试表 t2,有主索引 id 和 辅助索引 ch,分析 t2.ibd 文件可验证:
  • 对比表t,表t2多一个INDEX页,用于存储辅助索引的根结点 。
  • 辅助索引的INDEX页也有两个系统记录 infimum 和 supremum 。而用户记录内容格式跟前面分析基本一致,内容为辅助索引 ch 列的值 ab 和 主键值1 。
页目录前面提到INDEX页内的记录是通过单向链表连接在一起的,遍历列表性能会比较差,而INDEX页的页目录就是为了加速记录搜索 。表 t2 中的页目录只有两项,分别是 0x63 和 0x70,即 99 和 112 。
下面的ownedkey为这个页目录槽拥有的小于等于它的记录数目,显然 infimum 的ownedkey为 1,即只有它自己,没有key会比infimum小 。而 supremum 的owned是3,分别是我们插入的两条记录和它自己 。
slot    offset  type          owned  key0       99      infimum       1       1       112     supremum      3 每个页目录槽最少要包含4个记录,最多包含8个记录(包括它自己) 。如果我们在表 t2 中另外插入 7 条记录,则会增加一个新的slot,即 id 为 4 的记录,如下:
slot    offset  type          owned   key0       99      infimum       1       1       207     conventional  4       (i=4)2       112     supremum      5  下图是页目录结构图,可以通过页目录的二分查找提高页内数据的查询性能 。
为什么别人能用好 MySQL?万字详解其复杂原理

文章插图
 
页目录结构
3.4 InnoDB 系统表空间系统表空间包含内容有:数据字典,双写缓冲,修改缓冲,undo日志,以及在系统表空间创建的表的数据和索引 。可以看到,除了分配未使用的页外,UNDO_LOG,SYS, INDEX 页占据了不少的空间 。UNDO_LOG 页存储的是Undo log,SYS 页存储的是数据字典、回滚段、修改缓存等信息,INDEX 是索引页,TRX_SYS 页用于InnoDB的事务系统 。数据字典就是数据表的元信息,修改缓冲前面提到是为了提高IO性能也不再赘述,这里主要分析下 Undo 日志和双写缓冲 。
root@stretch:/home/vagrant# innodb_space -s /var/lib/mysql/ibdata1 space-page-type-summarytype                count       percent     description         ALLOCATED           427         55.60       Freshly allocated   UNDO_LOG            125         16.28       Undo log            SYS                 110         14.32       System internal     INDEX               71          9.24        B+Tree index        INODE               11          1.43        File segment inode  FSP_HDR             9           1.17        File space header   IBUF_BITMAP         8           1.04        Insert buffer bitmapBLOB                5           0.65        Uncompressed BLOB   TRX_SYS             2           0.26        Transaction system header


推荐阅读