【问题标题】:Out of memory when doing a big query?执行大查询时内存不足?
【发布时间】:2013-04-20 13:43:42
【问题描述】:

我在尝试进行大查询时收到此错误。

java.lang.OutOfMemoryError: Java heap space

我搜索并发现将 setAutoCommit(false)setFetchSize 方法应用于我准备好的语句可能有助于处理大查询。 但是,当我使用它时,我收到了这个错误。

java.sql.SQLException: Illegal value for setFetchDirection().

处理大型查询的正确和简单的方法是什么?

使用 setFetchSize 的正确方法是什么?

【问题讨论】:

  • 使用示例代码提供建议会更容易。不过,这种事情最常见的答案是将查询分解成更易于管理的块。您真的需要一次获得所有这些数据吗?
  • SQL 控制台上运行相同查询时得到多少行,也可以尝试为java 增加heap_size
  • @Simonatmso.net - 恐怕我不能分享。但我能说的是查询字符串没有优化,有些可怕。太糟糕了,修改它并不容易(在我开始工作之前它已经很糟糕了;P)。
  • @Akash 我也尝试过“LIMIT 0,1”,但仍然无法查询。我会检查 heap_size。对不起,我忘了提到我使用 java、JDBC 和 mysql。

标签: java mysql heap-memory large-query


【解决方案1】:

假设你使用的是MySQL提供的MySQL Connector/J驱动,相信在this manual page中可以找到解决方法(注意Connection::createStatement()的参数1):

如果您正在使用具有大量行的结果集或 值很大,并且无法在 JVM 中为 需要内存,您可以告诉驱动程序将结果流回 一次一行。

要启用此功能,请按以下方式创建 Statement 实例:

stmt = conn.createStatement(java.sql.ResultSet.TYPE_FORWARD_ONLY,
              java.sql.ResultSet.CONCUR_READ_ONLY);
stmt.setFetchSize(Integer.MIN_VALUE);

【讨论】:

  • 是否可以将 setFetchSize 与准备好的语句一起使用?
  • 因为public interface PreparedStatement extends Statement,我想是的。同样,我会考虑使用方法Connection::prepareStatement(String sql, int resultSetType, int resultSetConcurrency) 来创建这样的PreparedStatement
【解决方案2】:

也许做一个懒惰的搜索,例如只提取 ID 或其他东西,然后当你想使用/显示你的数据时,只对那个 ID 进行查询?

或者也许改为在一个线程中运行它,这样它就可以在后台运行并执行它

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-04
    • 2013-06-07
    • 2019-11-07
    • 1970-01-01
    • 2015-08-02
    • 1970-01-01
    相关资源
    最近更新 更多