MyISAM存储引擎的碎片整理问题
最近,在使用MySQL数据库的MyISAM存储引擎建表,并且在删除大量数据时,发现在本地硬盘放置的的data文件并没有改变大小。碰到这种情况,笔者甚是郁闷而又感到奇怪,经查阅资料,终于解决了该问题。
问题的根源是该数据库表产生了大量的碎片,只要进行碎片整理即可解决问题,现整理如下,方便以后查阅 :)
关键操作:
|
|
现在创建一个MyISAM引擎表test_one:
|
|
插入测试数据:
|
|
pic
现在删除id=3的数据:
|
|
执行完毕,查看硬盘数据保存文件大小,看大小是否减为原来的三分之一:
pic
发现,文件大小并没有减小,说明产生了碎片。当使用MyISAM引擎时,可以使用optimize命令来优化数据库,进行碎片整理:
|
|
pic
接下来查看硬盘文件大小是否改变:
pic
此时,保存在硬盘的数据文件发生了改变,减小了三分之一,说明使用optimize确实进行了碎片整理。
也许,会有人问,那假如我使用的是InnoDB引擎建表的呢?
首先,我们要查看innodb_file_per_table(是否独享表空间)
|
|
pic
OFF代表开启共享表空间没有打开,即采用的是默认的共享表空间。这个时候可以在mysql的datadir路径下看到一个非常大的文件ibdata1,这个文件存储了所有InnoDB表的数据与索引。
如果test_one表是InnoDB引擎,当我们执行如下命令:
|
|
此时,会返回Table does not support optimize, doing recreate + analyze instead,即代表optimize无法优化表。
这个时候,可以使用如下命令来优化表:
|
|
输出如下信息: pic
另一种情况,如果开启了独享表空间,即每张表都有ibdfile。这个时候如果删除了大量的行,索引会重组并且会释放相应的空间因此不必优化。
小结:
使用optimize命令可以进行数据表的碎片整理,从而对表进行优化。
但是要注意,OPTIMIZE 操作会暂时锁住表,而且数据量越大,耗费的时间也越长,它毕竟不是简单查询操作.所以把 Optimize 命令放在程序中是不妥当的,不管设置的命中率多低,当访问量增大的时候,整体命中率也会上升,这样肯定会对程序的运行效率造成很大影响.比较好的方式就是做个 Script,定期检查mysql中 information_schema.TABLES字段,查看 DATA_FREE 字段,大于0话,就表示有碎片.脚本多长时间运行一次,可以根据实际情况来定,比如每周跑一次.
(end)
- 原文作者:maratrix
- 原文链接:https://maratrix.cn/post/2014/10/19/mysql_myisam_data_optimize/
- 版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议进行许可,非商业转载请注明出处(作者,原文链接),商业转载请联系作者获得授权。