2011-04-14 72 views
1

生产数据库中有大量数据,我想用批数据进行更新,而表中的数据仍可供最终用户使用。更新可以插入新行或更新现有行。具体的表格大约有50M行,更新将在每批“批量”100k到1M行之间。我想要做的是以低优先级插入替换。换句话说,我希望数据库能够缓慢地进行批量导入,而不会影响同时发生在相同磁盘主轴上的其他查询的性能。更复杂的是,更新数据的索引很大。 8个跨越多列的b-tree索引,以促进各种查找,这会增加导入的相当多的开销。在生产数据库中更新大量数据

我曾经想过把插入物分成1-2k个记录块,然后让外部脚本加载数据只是在每个插入点之间暂停几秒钟,但这真是一种嗜好的恕我直言。另外,在1M记录批次期间,如果不需要,我真的不想添加500-1000次2秒暂停以增加20-40分钟的额外加载时间。任何人有更好的方式来做到这一点的想法?

+0

等待低活动期,或如您所建议的,使批次小得多。 – Randy 2011-04-14 21:34:09

回答

2

我已经处理了一个使用InnoDB和数亿行的类似场景。如果要将最终用户的风险降至最低,则使用限制机制进行批处理是方法。我会尝试不同的停顿时间,看看有什么适合你的。对于小批次,您可以获得相应调整的好处。如果按顺序运行,您可能会发现不需要任何暂停。如果您的最终用户使用更多的连接,那么他们自然会获得更多的资源。

如果您使用的是MyISAM,则有UPDATE的LOW_PRIORITY选项。如果您使用InnoDB进行复制,请务必检查它是否因为额外负载而落后。显然它运行在一个单一的线程中,这对我们来说是一个瓶颈。因此,我们对节流机制进行了编程,以检查复制到底有多远,并根据需要暂停。

0

检查此链接:http://dev.mysql.com/doc/refman/5.0/en/server-status-variables.html我会做的是编写一个脚本,当MySQL显示Threads_running或连接在一定数量下时,脚本将执行您的批量更新。希望你有某种测试服务器,你可以确定这些服务器变量的好数字阈值。还有很多其他的服务器状态变量。也许通过Innodb_data_pending_writes数字来控制执行?让我们知道什么适合你,它是一个有趣的问题!

2

INSERT DELAYED可能是你需要的。从链接的文档:

delayed_insert_limit行写入每一次,处理器检查是否任何SELECT语句仍悬而未决。如果是这样,它允许这些在继续之前执行。

+0

我一直在看这个,但文档说它会忽略延迟,如果有一个重复的密钥更新。 – Zak 2011-04-14 22:40:24

+0

还有一个[REPLACE DELAYED](http://dev.mysql.com/doc/refman/5.0/en/replace.html)。不幸的是,在这种情况下DELAYED的工作原理没有解释。 – Oswald 2011-04-14 23:05:41