我有一张 1760 万行的表
'CREATE TABLE `tmp_hist` (
`ti` int(11) DEFAULT NULL,
`cip6` varchar(15) DEFAULT NULL,
`date` varchar(20) DEFAULT NULL,
`fact` int(11) DEFAULT NULL,
`se` char(1) DEFAULT NULL,
`oper` int(11) DEFAULT NULL,
`qte` int(11) DEFAULT NULL,
`prix` double DEFAULT NULL,
`cip` int(11) DEFAULT NULL,
`fl` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1'
运行一个非常简单的更新大约需要 10 分钟
update tmp_hist set cip=100
有的时候:
- 39sec -- 修复表 tmp_hist(这个特别有趣,因为在 myisam 中,修复表会将其复制到不同的文件并替换原始文件,这表明磁盘速度)
- 531sec -- 更新 tmp_hist 设置 cip=100
- 400sec -- CREATE TABLE tmp_inno SELECT * FROM tmp_hist (这里我尝试将表转换为 InnoDB)
- 317sec -- 更新 tmp_inno 设置 cip=999(这个在 InnoDb 中)
根据所有假设,我希望更新时间与修复时间非常相似,即 40 秒。但是需要10分钟!可以做些什么来加快速度?有问题的代码将一些数据从格式 A 转换为格式 B。它保证在单个线程中运行,没有其他人访问相同的数据,如果出现任何问题,也不需要恢复,它可以重新开始。
PS:为了测试,UPDATE 语句被简化了(所有时间都是为了这个简化的更新)。真实代码为每一行设置不同的值,但我发现真实更新的执行时间与简化更新几乎相同,所以我将问题缩小到简化。
目前的进展
使用答案中的知识,我应用了 ROW_FORMAT=FIXED (这似乎相当于将所有列类型更改为固定)并将更新时间减少到 145 秒,几乎快了 4 倍。
尽管如此,它还是比修复时间慢了大约 2.5 倍,我认为这是可以达到的时间。