【发布时间】:2013-10-25 21:55:31
【问题描述】:
要求:我必须扫描整个表并更新每一条记录,周期。
根据其他人的建议,我应该创建一个与原始表具有相同架构的临时表并插入更新的值,然后重命名表而不是更新原始表。
这个想法是这样的:
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 | NON-SCROLLABLE 等。或者 Mysql 服务器是否有一些配置可以做一些聪明的事情,比如 mysql 知道我正在做全表扫描,所以只是按顺序为我返回记录,但不是一次全部返回。
欢迎任何建议
[UPDATE] 似乎 MySQL 连接器/J 具有名为 useCursorFetch 的配置参数,如果设置为 true,则 statement.setFetchSize(1000) 将起作用。不确定这是否是最终解决方案。
【问题讨论】:
-
如果您对更新所涉及的内容有所了解,将会有所帮助。如果更新相对简单,并且您使用的是 MySQL,您可能会很好地查看
SELECT INTO OUTFILE和LOAD DATA INFILE -
谢谢迈克,这是一次重要的更新,涉及长度操作:(