【问题标题】:large sql resultsets in javajava中的大型sql结果集
【发布时间】:2023-04-05 07:19:02
【问题描述】:

如何在 java 中获取大型结果集?我有大约 140,000 行 3 列。

【问题讨论】:

  • 好吧,就像在 java 中获取小结果集一样。你有什么顾虑?性能、内存使用、...?

标签: java sql performance oracle jdbc


【解决方案1】:

没有特殊的方法可以检索大型结果集;这可以像通过 JDBC 进行的任何其他数据库查询一样完成。

关键在于如何处理结果。 140,000 条小记录并不算多,但如果一次将它们全部保存在应用程序内存中是一个问题,请考虑是否可以“流式”处理它们。也就是说,使用每条记录所需的信息,然后在检索下一条记录之前丢弃该记录。这样,内存需求就不再取决于结果集中的记录数。

【讨论】:

  • 如果我没记错的话,你也可以使用 JDBC 内置的分页。
  • 为了避免内存问题,流式传输确实是要走的路。
  • 丢弃记录是什么意思
  • @Rams 我很确定这意味着从本地内存中丢弃,而不是从原始数据库中丢弃(如果这就是您的意思)。
  • “丢弃”是指取消引用该记录中的所有数据,以便对其进行垃圾收集。因此,如果您从每行中的字段创建 Java 对象,请不要尝试保留对从所有行创建的所有对象的引用。为一行创建一个对象,使用它,然后移动下一个,失去对前一个对象的引用,以便收集它。
【解决方案2】:

(使用 java.sql.Connection 到您的数据库):

Statement st = cnxn.createStatement();
ResultSet rs = st.executeQuery("SELECT column1,column2,your_mom FROM some_table");

while(rs.next()){
  Object ob1 =  rs.getObject(1);
  Object ob2 =  rs.getObject(2);
  Ho ob3 =  rs.getHo(3);
  doStuffWithRow(ob1,ob2,ob3);
}

除非您的 DBMS 毫无用处,否则结果将按要求从磁盘/内存中读取,并且不会留在您的内存中或任何类似的疯狂内容中。使用基于基元的 ResultSet.getXXX 方法比 getObject 更快,但我不想指定列类型。

请耐心等待。哦,在这里远离 ORM。

【讨论】:

  • 我刚刚在 Postgres 9.1 上尝试过——它试图将整个表提取到内存中!
  • 啊哈 - Postgres 特有的问题 - 我将在单独的答案中发布解决方案。
  • 要使用 jdbc postgresql 驱动程序执行此操作,您需要在 connection 上调用 setAutoCommit(false),然后在 preparedStatement 上调用 setFetchSize(FETCH_SIZE)。但是流式获取 api 是按驱动程序实现的,并且在整个 jdbc 上并不一致。很烦人。
【解决方案3】:

如果您使用的是 PostgreSQL,则需要按如下方式设置连接和语句:

Connection cnxn = ...;
cnxn.setAutoCommit(false);   
Statement stmnt = cnxn.createStatement();
stmnt.setFetchSize(1);

否则,您的查询可能会尝试将所有内容加载到内存中。 感谢 http://abhirama.wordpress.com/2009/01/07/postgresql-jdbc-and-large-result-sets/ 记录这一点。

【讨论】:

    【解决方案4】:

    我会避免使用任何类型的复杂抽象加载这样的数据集。这听起来像是一个“批处理作业”风格的应用程序。

    我会推荐使用原始 jdbc 并将其映射到一个非常紧凑的表示,没有膨胀只有 3 列这应该很容易保存在内存中,如果字符串?不会太大。

    避免使用 hibernate 等工具加载 140k 行。这是一个很棒的工具,但如果你在休眠的一级和二级缓存中保存了这么多实体,你可能会遇到内存问题。

    【讨论】:

      【解决方案5】:

      我建议使用批处理样式获取而不是加载所有内容。执行具有大结果集的查询时,在数据库端有性能考虑。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-11-29
        • 1970-01-01
        • 2012-02-16
        • 2012-01-24
        • 2010-10-23
        • 2011-01-31
        • 1970-01-01
        • 2012-02-07
        相关资源
        最近更新 更多