简单的说,删除数据必然会在数据文件中形成不连续的空白空间,而当插入数据时,这些空白空间则会被利用起来。因而形成了数据的存储位置不连续,以及物理存储顺序与理论上的排序顺序不一样,这种是数据碎片。 实际上数据碎片分为两种,一种是单行数据碎片,另外一种是多行数据碎片。前者的意思就是一行数据,被分红N个片断,存储在N个位置。后者的就是多行数据并未按照逻辑上的顺序排列。 当有大量的删除和插入操做时,必然会产生不少未使用的空白空间,这些空间就是多出来的额外空间。 索引也是文件数据,因此也会产生索引碎片,理由同上,大概就是顺序紊乱的问题。 Engine 不一样,OPTIMIZE 的操做也不同的,MyISAM 由于索引和数据是分开的,因此 OPTIMIZE 能够整理数据文件,并重排索引。 InnoDB 使用的 Clustered Index,索引和数据绑定在一块儿,重排序是不现实的。因此不支持 MyISAM 式的 OPTIMIZE,而是绑定到了 ALTER TABLE 命令上面。当执行优化操做时,实际执行的是一个空的 ALTER 命令,可是这个命令也会起到优化的做用,它会重建整个表,删掉未使用的空白空间... OPTIMIZE 操做会暂时锁住表,并且数据量越大,耗费的时间也越长,它毕竟不是简单查询操做。 因此把 Optimize 命令放在程序中是不稳当的,无论设置的命中率多低,当访问量增大的时候, 总体命中率也会上升,这样确定会对程序的运行效率形成很大影响。 比较好的方式就是作个 Script,按期检查 `information_schema`.`TABLES`,查看 DATA_FREE 字段,大于0话,就表示有碎片。脚本多长时间运行一次,能够根据实际状况来定,好比每周跑一次。