繁体   English   中英

Mysql InnoDB并快速应用大型更新

[英]Mysql InnoDB and quickly applying large updates

基本上,我的问题是我有一张大约有17,000,000种产品的大表,我需要快速应用大量更新。

该表有30列,其ID设置为int(10)AUTO_INCREMENT。

我有另一个表,该表的所有更新都存储在其中,这些更新必须预先计算,因为它们需要几天的时间才能计算出来。 此表是在格式为[PRODUCT_ID INT(10),update_value INT(10)]。

我要迅速发布这1700万个更新的策略是将所有这些更新加载到ruby脚本中的内存中,并将它们分组为一个数组的哈希,以便每个update_value是一个键,每个数组是一个排序后的product_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);

我很确定我正确地做到了这一点,因为在product_id的已排序批次上发布更新应该是使用mysql / innodb的最佳方式。

我打一个奇怪的问题,虽然在那里,当我与更新-13万条记录测试,这个只用了约45分钟。 现在,我正在测试更多数据,约1,700万条记录,并且更新需要近120分钟的时间。 我本来希望某种速度会降低,但不会达到我所看到的程度。

关于如何加快此记录速度或导致此较大记录集减慢速度的任何建议?

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

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

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

这样,它是数据库的一次传递和mysql可以通过其进行的单个大查询

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

假设product_id的查询分布是随机的,则每个更新SQL都会导致随机索引页访问。 当然,跟随索引页访问的数据页访问也是随机的。 如果要使所有更新快速运行,则需要(至少)要在内存中存储所有索引页。因此,这不是快速的更新操作集。

如果我正在设计它并且不需要进行事务更新,那么将像这样不在事务中按照product_ids逐行更新所有行:

UPDATE product SET update_value = 150 WHERE product_id = 1
UPDATE product SET update_value = 150 WHERE product_id = 2
...

由于这将导致索引页和数据页都被顺序读取/更新,因此此方案可能需要较长的更新时间,但从缓存管理的角度来看要便宜得多。 当然,对数据库的总体影响是最小的,因此除更新(如来自客户的查询)之外的其他操作不会降低。

如果需要事务操作,我可能希望有两个表,或者使用一些技巧将两个逻辑表合并为一个表,从上面的缓存讨论的角度来看,这比较便宜。 但是,如果您不需要事务处理,则可以按照每个product_id缓慢的更新。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM