如何避免从大表中检索所有记录时出现OOM(内存不足)错误?

我被赋予了一个任务,将一个巨大的表转换为自定义XML文件。我将使用Java来完成这项工作。

如果我只是发出“从客户那里选择*”,它可能会返回大量数据,最终导致OOM。我想知道,有没有办法在记录可用后立即处理它,并在sql检索过程中从内存中删除记录?

---编辑于2019年7月13日

让我详细阐述我的问题。我有 1 个数据库服务器和 1 个应用程序服务器。当我在应用程序中发出选择查询时,数据将从数据库服务器传输到应用程序服务器。

我相信(如果我错了,请纠正我)ResultSet将需要等到收到查询中的所有记录。即使我们将抓取大小设置为4,对于1000条记录的表,我们仍然最终在应用服务器的堆内存中有1000条记录,这是正确的吗?提取大小仅影响从/到数据库服务器的往返次数。

我的问题是,如何在4条(或任何数字)记录到达应用程序服务器后立即开始处理,并处理它以释放应用程序服务器的内存?


答案 1

有了更多的信息,我就可以得到一个更有用的答案。

如果您使用的是 MySQL:

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

http://www.oracle.com/technology/tech/java/sqlj_jdbc/htdocs/jdbc_faq.html

java.util.Properties info = new java.util.Properties();
info.put ("user", "scott");
info.put ("password","tiger");
info.put ("defaultRowPrefetch","15");
getConnection ("jdbc:oracle:oci:@",info);

答案 2

我认为您可以使用与此相同的解决方案。可滚动的结果集。


推荐