MySQL从300万行表中更新每一行

时间:2013-09-15 22:05:16

标签: mysql jdbc

要求:我必须扫描整个表并更新每个记录,期间。

正如其他人所建议的那样,我应该创建一个与原始模式具有相同模式的临时表,然后插入更新的值,然后重命名表而不是更新原始表。

这个想法是这样的:

ResultSet row = select * from old_table;
While row.next
  do something to update values in this row
  insert updated values in to a identical table (different name of course)
endWhile

这里的问题是我使用的是Java JDBC,我必须处理ResultSet对象。那么有没有办法防止“ResultSet row = select * from old_table”生成内存不足异常?

一个潜在的解决方案是分页,但这意味着我必须使用ORDER BY和LIMIT,这在300万行表上可能会非常慢。

是否有一些关于ResultSet的技巧,比如指定一些标志,如FOWARD_ONLY |不可滚动等等。或者Mysql服务器有一些配置来做智能的东西,比如mysql理解我正在做一个全表扫描,所以只是顺序返回记录给我,但不是一次性。

欢迎任何建议

[UPDATE]似乎MySQL connector / J具有名为useCursorFetch的配置参数,如果设置为true,则statement.setFetchSize(1000)将起作用。不确定这是否是最终的解决方案。

1 个答案:

答案 0 :(得分:1)

您可以通过以下方式将JDBC语句设置为非缓冲:

stmt.setFetchSize(Integer.MIN_VALUE); 

但我也建议使用INSERT... SELECT语句,因此您不必使用while循环而不必获取任何内容。如果您可以使用SQL表达式执行“执行某些更新值”的步骤,那么您可以在一个SQL语句中执行整个操作。

PS:你必须更具体地了解QuerySet。我在不同的库中找到了多个名为QuerySet的类,例如org.dbunit.ant.QuerySet,org.gusdb.wdk.model.QuerySet等。

相关问题