对于名为mydb.mytable的MySQL表,只需运行以下命令:
OPTIMIZE TABLE mydb.mytable;
您也可以分阶段进行:
CREATE TABLE mydb.mytable_new LIKE mydb.mytable;
ALTER TABLE mydb.mytable_new DISABLE KEYS;
INSERT INTO mydb.mytable_new SELECT * FROM mydb.mytable;
ALTER TABLE mydb.mytable_new ENABLE KEYS;
ALTER TABLE mydb.mytable RENAME mydb.mytable_old;
ALTER TABLE mydb.mytable_new RENAME mydb.mytable;
ALTER TABLE mydb.mytable_old;
ANALYZE TABLE mydb.mytable;
无论哪种情况,表都不会出现碎片.
试试看 !!!
更新2012-12-03 12:50 EDT
如果您担心是否通过LOAD DATA INFILE在大容量INSERT上重用行,请注意以下几点:
当您创建MyISAM表时,我假设默认的行格式是动态的.您可以检查其中之一
SHOW CREATE TABLE mydb.mytable\G
要么
SELECT row_format FROM information_schema.tables
WHERE table_schema='mydb' AND table_name='mytable';
由于表的行格式是动态的,因此分散的行具有各种大小. MyISAM存储引擎将一直检查每个删除的行的长度,以查看是否要插入下一组数据.如果输入的数据不能容纳在任何已删除的行中,则将附加新的行数据.
这就是为什么我建议运行OPTIMIZE TABLE的原因.这样,数据将被更快地附加.
更新2012-12-03 12:58 EDT
您也可以执行以下操作:Try setting concurrent_insert to 2.那样,您总是在不检查表中的间隙的情况下追加到MyISAM表中.这将极大地加快INSERT的速度,但将所有已知的空白都保留下来.
您仍可以使用OPTIMIZE TABLE尽早对表进行碎片整理.
更新2012-12-03 13:40 EDT
为什么不进行第二次建议
CREATE TABLE mydb.mytable_new LIKE mydb.mytable;
ALTER TABLE mydb.mytable_new DISABLE KEYS;
INSERT INTO mydb.mytable_new SELECT * FROM mydb.mytable;
ALTER TABLE mydb.mytable_new ENABLE KEYS;
ALTER TABLE mydb.mytable RENAME mydb.mytable_old;
ALTER TABLE mydb.mytable_new RENAME mydb.mytable;
ANALYZE TABLE mydb.mytable;
这会给你一个想法
> OPTIMIZE TABLE需要花费多长时间
>运行优化表后.MYD和.MYI会缩小多少
运行第二条建议后,您可以将它们与
SELECT
A.mydsize,B.mydsize,A.mydsize - B.mydsize myd_diff,
A.midsize,B.myisize,A.myisize - B.myisize myi_diff
FROM
(
SELECT data_length mydsize,index_length myisize
FROM information_schema.tables
WHERE table_schema='mydb' AND table_name='mytable'
) A,
(
SELECT data_length mydsize,index_length myisize
FROM information_schema.tables
WHERE table_schema='mydb' AND table_name='mytable_new'
) B;
更新2012-12-03 16:42 EDT
ROW_FORMAT设置为固定的任何表都可以每次分配相同长度的行.如果MyISAM表维护一个已删除行的列表,则应始终选择列表中的第一行作为下一行以插入数据.在找到具有足够长度的合适行间隙之前,将不需要遍历整个列表.每个删除的行都会在DELETE之后快速添加.每个INSERT都会选择已删除行的第一行.
我们可以假设这些是因为MyISAM tables can do concurrent inserts.为了使该功能通过concurrent_insert选项可用,将INSERT插入MyISAM表必须能够检测三(3)件事之一:
>存在已删除行的列表,因此可以从列表中进行选择
> Row_Format = Dynamic:删除的行的列表,每行的长度不同
> Row_Format =固定:所有行的长度都相同的已删除行的列表
>缺少删除行的列表,因此追加
>绕过检查是否存在已删除行的列表(将concurrent_insert设置为2)
为了使检测#1尽可能快,必须将MyISAM表的row_format固定.如果是动态的,则很有可能需要遍历列表.