要求:我必须扫描整个表并更新每个记录,期间。
正如其他人所建议的那样,我应该创建一个与原始表具有相同架构的临时表,并在更新后的值上进行插入,然后重命名表而不是在原始表上进行更新。
这个想法是这样的:
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连接器/ J具有名为的配置参数useCursorFetch
,如果设置为true,则statement.setFetchSize(1000)
可以使用。不知道这是否是最终解决方案。
您可以通过以下方式将JDBC语句设置为非缓冲:
stmt.setFetchSize(Integer.MIN_VALUE);
但是我也建议使用一条INSERT... SELECT
语句,这样您就不必使用while循环,也不必获取任何内容。如果您可以在执行“一些操作以更新值”的步骤中使用SQL表达式,则可以在一条SQL语句中完成整个操作。
PS:您必须更具体地了解QuerySet。我在不同的库中找到多个称为QuerySet的类,例如org.dbunit.ant.QuerySet,org.gusdb.wdk.model.QuerySet等。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句