我在Groovy中编写了一个非常复杂的数据库迁移脚本,它在我的工作站上运行得很好,但在服务器的JVM上运行时会产生“Caught:java.lang.OutOfMemoryError:Java堆空间”。 JVM保持原样(作为实习生的资源有限),所以除了增加可用内存之外,我还需要找出解决这个问题的另一种方法。
当访问一些最大的表时出现错误:一个特别大但很简单的连接(200,000多行到50,000多行)。有没有其他方法可以接近这样的联接,这将使我免于错误?
查询示例:
target.query("""
SELECT
a.*, b.neededColumn
FROM
bigTable a JOIN mediumTable b ON
a.stuff = b.stuff
ORDER BY stuff DESC
""") { ResultSet rs ->
...
}
答案 0 :(得分:2)
您可以在数据库服务器上运行SQL连接吗?
如果没有,你可能会坚持迭代你的200,000个结果中的每一个,将它加入50,000行并写出结果(所以你不会在任何时候在内存中存储超过1 * 50,000的结果)
或者,如果您可以访问多台计算机,您可以将200,000个项目划分为多个块并为每台计算机执行一个块?
修改强> 的
使用您的示例代码,您应该可以:
new File( 'output.csv' ).withWriter { w ->
target.eachRow( '''SELECT a.a, a.b, a.c, b.neededColumn FROM
bigTable a
JOIN mediumTable b ON a.stuff = b.stuff
ORDER BY stuff DESC''' ) { row ->
w.write "$row.a,$row.b,$row.c,$row.neededColumn"
}
}
这会将每一行写入文件output.csv
答案 1 :(得分:1)
您必须更改代码,以便不会同时将所有行全部加载到内存中(即,流式传输数据,一次一行地处理每一行)。据我所知,当您使用collect
之类的东西时,Groovy仍然不会这样做,所以重写它以使用for循环。