我有这张桌子:
CREATE TABLE `foo` (
`CalculatedResultsId` int NOT NULL,
`Md5Hash` char(32) CHARACTER SET latin1 COLLATE latin1_general_ci NOT NULL,
`SectionData` json NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci;
ALTER TABLE `foo`
ADD UNIQUE KEY `CalculatedResultsId` (`CalculatedResultsId`),
ADD UNIQUE KEY `Md5Hash` (`Md5Hash`);
其中包含约 400k 行,大小约为 800MB。这是 PMA 的输出:
然后我删除 2'454 行 [< 0.6%],这会产生大约 5MB 的开销,这也在PMA 中记录:
跑步OPTIMIZE Table
突然使这张桌子的大小增加了一倍。我检查了目录中表文件的实际大小,这是正确的。真的翻倍了!
我的问题:
为什么,这是怎么回事?发生了什么事,是什么原因,桌子大小翻了一番?
我发现如何像以前一样减小表格大小的唯一方法是创建一个新表格并重新填充它。另一个非常奇怪的事实:
运行此命令以获取大表的副本CREATE TABLE foo_new AS SELECT * FROM foo;
运行 27!这 400k 行的分钟数。
创建一个空表,然后复制INSERT INTO foo_new SELECT * FROM foo
需要 24!秒。
为什么会有这样的差异?我不知道,但不知何故,它在我看来像是 MySQL 中一个非常严重的设计问题,或者是一个错误。
在 SLES 15.1 上运行的 MySQL 8.0.20
这是 4 个月前提交的错误,它已在 MySQL 8.0.22 中修复。
至于复制的缓慢性——对于每一行,它必须检查每个
UNIQUE
索引中是否已经存在重复。两种解决方法(也许):
key_buffer_size
。CREATE
没有索引的表,然后是ADD
它们。