MySQL 17.6m行(1.2 gb)全表更新速度太慢

时间:2012-12-06 10:00:17

标签: mysql

我有一张17.6米行的表

'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 set cip = 100
  • 400sec - CREATE TABLE tmp_inno SELECT * FROM tmp_hist(这里我尝试将表转换为InnoDB)
  • 317sec - 更新tmp_inno set cip = 999(InnoDb中的这个)

根据所有假设,我预计更新时间与修复时间非常相似,即40秒。但它需要10分钟!可以做些什么来加快速度?有问题的代码将一些数据从格式A转换为格式B.它保证在单个线程中运行而没有其他任何人访问相同的数据,如果出现任何问题则不需要恢复,它可以刚刚重新开始。

PS:UPDATE语句被简化用于测试(并且所有时间都用于此简化更新)。真实代码为每一行设置不同的值,但我发现实际更新的执行时间与简化更新的执行时间几乎相同,因此我将问题范围缩小到简化。

当前进度

使用答案中的知识,我应用了ROW_FORMAT = FIXED(看起来等同于将所有列类型更改为固定),并将更新时间减少到145秒,这几乎快了4倍。

然而,它比修复时间慢了约2.5倍,我认为这是可以达到的时间。

1 个答案:

答案 0 :(得分:4)

由于表中有varchar,因此更新必须读取行,查找正确的偏移量,然后更新cip字段。此外,由于行是可变大小的,因此引擎不能容易地确定单个记录的偏移。因此,您可以尝试将varchar字段更改为固定char并进行测试,如果这样做有所不同。

关于这个话题的一个有趣的答案是在dba SE https://dba.stackexchange.com/a/2643

结束