我有一个巨大的表,我正在尝试流式传输到文件。然而,似乎无论我尝试什么,Postgres都试图立即拉出所有数据并耗尽内存。我在这里和其他地方读过很多帖子,我觉得我这样做是对的,所以为什么我的内存不足?
这是我的代码:
Connection conn = DriverManager.getConnection(dbUrl, dbUser, dbPassword);
conn.setAutoCommit(false);
conn.setReadOnly(true);
Statement ps = conn.createStatement(
ResultSet.TYPE_FORWARD_ONLY,
ResultSet.CONCUR_READ_ONLY,
ResultSet.HOLD_CURSORS_OVER_COMMIT);
ps.setFetchSize(10);
String sql = "SELECT * FROM BIGTABLE "
+ "WHERE '20150401' BETWEEN startdate AND enddate";
ResultSet rs = ps.executeQuery(sql);
writeResultSet(os, rs);
在内存不足之前,代码永远不会超过查询执行。
如果重要,则在流式传输到打开的ZipOutputStream时会发生在单独的线程中。此时,一个项目已经流出,我从未达到可以流出此表的程度。
我正在使用Postgres 9.3.5,目前将VM限制为128MB进行测试。虽然我可以增加堆大小,但我仍然认为我不应该遇到这个问题。
[jsyk,为了清楚起见,我已经删除了try / catch块等。]
答案 0 :(得分:1)
ResultSet.HOLD_CURSORS_OVER_COMMIT
此设置要求保留游标,该游标在Postgresql的客户端实现。 Postgresql本身不支持JDBC使用的协议(前端/后端协议)上的本机可保持游标。相关文章:
另请注意,即使本机可保持游标也有O(n)空间要求,但它将在磁盘上分配。
但是,通过查看代码,我发现没有理由需要一个可保持的游标。