【问题标题】:Postgres How can I get huge dataPostgres 如何获取大量数据
【发布时间】:2015-02-08 07:58:18
【问题描述】:

我有程序 java 客户端和 xmlrpc 服务器和 postgres DB,我正在从 2 个 DB 中检索数据,
我已向服务器发送 2 个查询,服务器将数据返回到 hashMap 内的客户端。

但是数据很大,有时它有超过 40000 行,如果我尝试获取它,我会从服务器收到错误说:java 堆空间

我正在尝试设置-Xmx1024m and -Xmx512m ... 没有任何好处

现在,修复它的最佳方法是什么?

我通过这段代码获取数据:

Class.forName("org.postgresql.Driver");
    String conString = "jdbc:postgresql://" + host + ":" + port + "/" + DBName + 
            "?user=" + user + "&pass=" + pass;
    String conString1 = "jdbc:postgresql://" + host + ":" + port2 + "/" + DBName2 + 
            "?user=" + user + "&pass=" + pass;  
      c = DriverManager.getConnection(conString);
      c2 = DriverManager.getConnection(conString1);

      st = c.createStatement();
      st2 = c2.createStatement();

          List<ResultSet> resultSets = new ArrayList<>();
          resultSets.add(st.executeQuery(query));
          resultSets.add(st2.executeQuery(query2));
      //ResultSet rs = st.executeQuery(query);
           ResultSets rs = new ResultSets(resultSets);
      while (rs.next()){
          unbArrL.add(rs.getUnbalance("unbalance"));
      }

ResultSets类获取值是:

class ResultSets {

 private java.util.List<java.sql.ResultSet> resultSets;

    private java.sql.ResultSet current;


    public ResultSets(java.util.List<java.sql.ResultSet> resultSets) {
        this.resultSets = new java.util.ArrayList<>(resultSets);
        current = resultSets.remove(0);
    }

    public boolean next() throws SQLException {
        if (current.next()) {
            return true;
        }else if (!resultSets.isEmpty()) {
            current = resultSets.remove(0);
            return next();
        }
        return false;
    }   
    public Double getUnbalance(String unbalance) throws SQLException{
        return current.getDouble("unbalance");
    }
}

你能给我清晰的解决方案和一些代码或例子吗?

【问题讨论】:

  • 使用LIMITOFFSET
  • 使用基于游标的结果集,否则所有内容都将加载到内存中。详细信息在文档中:jdbc.postgresql.org/documentation/94/…
  • 真的有必要将所有数据保存在内存中吗?做什么的?向用户显示 40.000 行似乎不是一个好主意。您可以在 Statement 实例上设置 setMaxRows。或者在你的 sql 中使用适当的 where 过滤器。或者你可以缓冲磁盘上的数据。

标签: java postgresql jdbc xml-rpc


【解决方案1】:

解决此问题的一个明显方法是将结果拆分到不同的页面并使用LIMITs 和 (OFFSETs)。

如果你真的需要一次输出整个数据集,你应该用结果填充一个集合,而是返回一个Iterable(或者只是一个Iterator,因为你'将只能迭代一次结果集)将一一获取数据库中的行,因为它们是由发出(格式化)响应的组件请求的。

因此,您需要将查询方法返回的所有Lists 替换为Iterators,并使IteratorhasNex()next() 方法调用底层中的相应逻辑数据库ResultSet

您也可以将原始 SQL ResultSet 一直返回到您的控制器,但这将是一个很差的关注点分离。

这种方法的最终结果是每次只获取一个行并将其发送到客户端输出流,因此无论您的查询有多大,您都会有一个恒定的内存占用。

【讨论】:

    猜你喜欢
    • 2020-06-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-27
    • 2020-11-28
    • 1970-01-01
    • 1970-01-01
    • 2020-09-16
    • 2016-07-12
    相关资源
    最近更新 更多