为什么我的 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 要求,但它会在磁盘上分配。

但是,通过查看您的代码,我看不出您需要可保持游标的原因。