14.12.4 对 table 进行碎片整理

随机插入二级索引或从二级索引中删除可能导致索引碎片化。碎片意味着磁盘上索引页的物理排序与页面上记录的索引排序不接近,或者 64 页块中有许多未使用的页已分配给索引。

碎片的一个症状是 table 占用的空间超过了它“应该”占用的空间。确切多少是很难确定的。所有InnoDB的数据和索引都存储在B-trees中,它们的fill factor的范围从 50%到 100%不等。碎片化的另一个症状是,这样的 table 扫描花费的时间比它“应该”花费的时间更多:

SELECT COUNT(*) FROM t WHERE non_indexed_column <> 12345;

前面的查询要求 MySQL 执行全 table 扫描,这是大型 table 的最慢查询类型。

为了加快索引扫描的速度,您可以定期执行“空” ALTER TABLE操作,这会使 MySQL 重建 table:

ALTER TABLE tbl_name ENGINE=INNODB

您也可以使用ALTER TABLE tbl_name 强制来执行“空”更改操作以重建 table。

ALTER TABLE tbl_name ENGINE = INNODBALTER TABLE tbl_name 强制都使用online DDL。有关更多信息,请参见第 14.13 节“ InnoDB 和在线 DDL”

执行碎片整理操作的另一种方法是使用mysqldump将 table 转储到文本文件,删除 table 并从转储文件重新加载它。

如果在索引中的插入始终递增,并且仅从末尾删除记录,则InnoDB文件空间 Management 算法可确保不会发生索引碎片。