Mysql InnoDB和快速应用大型更新

Mysql InnoDB和快速应用大型更新,mysql,ruby,database,innodb,Mysql,Ruby,Database,Innodb,基本上,我的问题是,我有一个大约17000000个产品的大表,我需要非常快速地应用一系列更新 该表有30列,id设置为int(10)AUTO_INCREMENT 我有另一个表,该表的所有更新都存储在其中,这些更新必须预先计算,因为它们需要几天的时间来计算。此表的格式为[产品标识int(10),更新值int(10)] 我快速发布这1700万个更新的策略是将所有这些更新加载到ruby脚本中的内存中,并将它们分组到数组的散列中,这样每个更新值都是一个键,每个数组都是一个已排序产品id的列表 {

基本上,我的问题是,我有一个大约17000000个产品的大表,我需要非常快速地应用一系列更新

该表有30列,id设置为int(10)AUTO_INCREMENT

我有另一个表,该表的所有更新都存储在其中,这些更新必须预先计算,因为它们需要几天的时间来计算。此表的格式为[产品标识int(10),更新值int(10)]

我快速发布这1700万个更新的策略是将所有这些更新加载到ruby脚本中的内存中,并将它们分组到数组的散列中,这样每个更新值都是一个键,每个数组都是一个已排序产品id的列表

{ 
   150: => [1,2,3,4,5,6],
   160: => [7,8,9,10]
}
然后以以下格式发布更新:

UPDATE product SET update_value = 150 WHERE product_id IN (1,2,3,4,5,6);
UPDATE product SET update_value = 160 WHERE product_id IN (7,8,9,10);
我很确定我做得很正确,因为在mysql/innodb中,对已排序的产品批次发布更新应该是最好的方式

我遇到了一个奇怪的问题,当我测试更新1300万条记录时,只花了大约45分钟。现在我用更多的数据进行测试,大约1700万条记录,更新需要将近120分钟。我本以为这里的速度会有所下降,但并没有达到我所看到的程度

有没有什么建议可以让我在这个更大的记录集上加快速度,或者是什么让我慢下来


就服务器规格而言,它们相当不错,内存/cpu堆积如山,整个数据库应该适合内存,并有足够的增长空间。

您可以尝试使用mysql的多表更新语法

update product, sometable SET product.update_value=sometable.value WHERE product_id=sometable.whatever;

这样一来,mysql只需通过一次数据库和一个大查询,就可以轻松地完成

我认为您需要仔细设计索引和数据页访问

假设
product\u id
s在查询中的分布是随机的,则每个更新SQL都会导致随机的索引页访问。当然,索引页访问之后的数据页访问也是随机的。如果你想让所有的更新快速运行,你需要在内存中有所有的索引页(至少是这样)。因此,这不是一个快速的更新操作集

如果我在设计它,并且不要求更新是事务性的, 我将按照每个产品标识逐个更新所有行,如下所示,而不是在事务中:

UPDATE product SET update_value = 150 WHERE product_id = 1
UPDATE product SET update_value = 150 WHERE product_id = 2
...
由于它将导致索引页和数据页按顺序读取/更新,因此该方案可能需要更长的更新时间,但从缓存管理的角度来看,成本要低得多。当然 对数据库的总体影响是最小的,所以除了更新之外的操作(比如来自客户的查询)不会降级


如果需要事务性操作,我可能希望有两个表,或者使用一些技巧将两个逻辑表合并到一个表中,这在上面的缓存讨论中是比较便宜的。但是,如果您不需要进行事务处理,那么按照
产品id
进行缓慢更新是一个不错的选择。

您是否调整了innodb设置,以便它能够利用您的“内存堆”?是的,服务器人员对这一设置进行了很好的调整。