在使用mysql的时候有时候,可能会发现尽管一张表删除了许多数据,但是这表表的数据文件和索引文件却奇怪的没有变小。这是因为mysql在删除数据(特别是有Text和BLOB)的时候,会留下许多的数据空洞,这些空洞会占据原来数据的空间,所以文件的大小没有改变。这些空洞在以后插入数据的时候可能会被再度利用起来,当然也有可能一直存在。这种空洞不仅额外增加了存储代价,同时也因为数据碎片化降低了表的扫描效率。
mysql提供了解决这一个问题的方法:optimize table table_name 命令。该命令会对表进行碎片整理,去除空洞。查看前后效果可以使用show table status命令,例如show table status from [database] like ‘[table_name]‘;返回结果中的data_free即为空洞所占据的存储空间。当执行完optimize table命令后,该字段的值将为0。
InnoDB类型的表是无法使用optimize table命令的。强行使用会返回如下结果:
不过使用alter table table_name engine=innodb也可以同样达到释放空洞的效果。这是由于在转换数据引擎(即便没有真正转换)的时候,mysql会将表中的数据读取出来,再重新写入,在这个过程中,空洞就自然没有了。
在对数据量小的表操作时,optimze table是挺快的,但是对一张有海量数据的表进行optimze table操作时,就很悲剧了,因为不但执行时间会很长,而且会锁表。这个时候就应该考虑使用一些运维手段避免现网的服务受到影响。