rss· 投稿· 设为首页· 加入收藏· 繁體版
当前位置: 火魔网 » 数据库 » MySQL

InnoDB表和索引结构

MySQL把表的数据词典信息以.frm文件的形式存在数据库目录里,所有MySQL存储引擎都是这样的。但是每个InnoDB表在表空间内的InnoDB内部数据词典里也有它自己的条目。当MySQL移除表或数据库,它不得不删除.frm文件和InnoDB数据词典内的相应条目。这就是为什么你不能在数据库之间简单地移动.frm文件来移动InnoDB表。


1、聚集索引和第二索引

每个InnoDB有一个叫聚集索引(clustered index)的特殊索引,行的数据被存于其中。

  • 如果你的表定义了主键,主键的索引就是聚集索引。
  • 如果你的表没有主键,MySQL就选择第一个不可为空的唯一索引(UNIQUE)作为主键,并且InnoDB把它作为聚集索引。
  • 如果你的表没有主键,也没有合适的唯一索引,InnoDB内部会在一个包含RowID的合成列上生成一个隐藏的聚集索引,其中是用InnoDB在分配给RowID来排序的。RowID是一个6字节的域,它在新行被插入的时候单调增加。因此被RowID排序的行是物理地按照插入顺序排的。

通过聚集索引访问行速度很快,因为行数据与索引扫描头部在同一数据页上。如果表是巨大的,当对于那些索引与数据放在不同数据页上的方案,聚集索引构架通常更节约磁盘I/O。(比如,MyISAM用一个文件存放数据,另外一个文件存放索引)。

在InnoDB中,非聚集索引里的记录(也称为辅助索引或第二索引)包含对应行的主键值。InnoDB用这个主键值从聚集索引中搜索行。注意,如果主键比较长,第二索引就会使用更多空间,因此最好使用一个比较短的主键。

2、索引的物理结构

所有InnoDB的索引是B树索引,这种索引记录被存储在树的叶子页上。一个索引页的默认大小是16KB。当新记录被插入,InnoDB会为将来索引记录的插入和更新留下十六分之一的页空间。

如果索引记录以连续的顺序被插入(升序或者降序),结果索引页大约是15/16满。如果记录被以随机的顺序被插入,页面是从1/2到 15/16满。如果索引页的填充因子降到低于1/2,InnoDB会收缩索引树来释放页。

3、插入缓冲

在数据库应用中,主键是一个唯一的识别符,并且新行被以主键的升序来插入,这是个常见的情况。因此,聚集索引的插入不需要磁盘的随机读。

另一方面,第二索引通常是非唯一的,第二索引的插入顺序也相对随机。这可能会导致大量的随机磁盘I/O操作,而没有一个被用在InnoDB中的专用机制。

如果一个索引记录应该被插入到一个非唯一第二索引,InnoDB检查第二索引页是否在缓冲池中。如果是,InnoDB直接插入到索引页。如果索引页没有在缓冲池中被发现,InnoDB插入记录到一个专门的插入缓冲结构。插入缓冲被保持得如此小以至于它完全适合在缓冲池,并且可以非常快地做插入。

插入缓冲周期性地被合并到数据库中第二索引树里。把数个插入合并到索引树的同一页,节省磁盘I/O操作,经常地这是有可能的。据测量,插入缓冲可以提高到表的插入速度达15倍。

在插入事务被提交之后,插入缓冲合并可能连续发生。实际上,服务器关闭和重启之后,这会连续发生。

当许多第二索引必须被更新,并且许多行已被插入之时,插入缓冲合并可能需要数个小时。在这期间内,磁盘I/O将会增加,这样会导致磁盘约束查询明显缓慢。另一个明显的后台I/O操作是净化(purge)线程

顶一下
(0)
踩一下
(0)