为什么我的 Postgres 游标 运行 内存不足?
Why is my Postgres cursor running out of memory?
我有一个巨大的 table 正试图流式传输到一个文件中。然而,似乎无论我尝试什么,Postgres 都试图一次提取所有数据并且 运行 内存不足。我在这里和其他地方阅读了 很多 个帖子,我想我正在这样做 "right",那么为什么我要让 运行 不在内存中?
这是我的代码:
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 时在单独的线程中发生的。在这一点上,一个项目已经流出,我还没有达到可以流出这个 table.
的地步
我正在使用 Postgres 9.3.5,目前将 VM 限制为 128MB 以进行测试。虽然我可以增加堆大小,但我仍然认为我不应该 运行 进入这个问题。
[jsyk,为清楚起见,我删除了 try/catch 块等。]
ResultSet.HOLD_CURSORS_OVER_COMMIT
此设置需要一个可持有的游标,它是在客户端为 Postgresql 实现的。 Postgresql 本身不支持 JDBC(Frontend/Backend 协议)使用的协议上的本机可持有游标。相关 post:
http://postgresql.nabble.com/New-significance-of-holdable-result-sets-in-Java-8-td5826656.html
另请注意,即使本机可持有游标也有 O(n) space 要求,但它会在磁盘上分配。
但是,通过查看您的代码,我看不出您需要可保持游标的原因。
我有一个巨大的 table 正试图流式传输到一个文件中。然而,似乎无论我尝试什么,Postgres 都试图一次提取所有数据并且 运行 内存不足。我在这里和其他地方阅读了 很多 个帖子,我想我正在这样做 "right",那么为什么我要让 运行 不在内存中?
这是我的代码:
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 时在单独的线程中发生的。在这一点上,一个项目已经流出,我还没有达到可以流出这个 table.
的地步我正在使用 Postgres 9.3.5,目前将 VM 限制为 128MB 以进行测试。虽然我可以增加堆大小,但我仍然认为我不应该 运行 进入这个问题。
[jsyk,为清楚起见,我删除了 try/catch 块等。]
ResultSet.HOLD_CURSORS_OVER_COMMIT
此设置需要一个可持有的游标,它是在客户端为 Postgresql 实现的。 Postgresql 本身不支持 JDBC(Frontend/Backend 协议)使用的协议上的本机可持有游标。相关 post:
http://postgresql.nabble.com/New-significance-of-holdable-result-sets-in-Java-8-td5826656.html
另请注意,即使本机可持有游标也有 O(n) space 要求,但它会在磁盘上分配。
但是,通过查看您的代码,我看不出您需要可保持游标的原因。