结果集中的fetchsize默认设置为0

时间:2013-12-10 14:05:52

标签: java mysql sql jdbc

我必须查询数据库,结果集非常大。我使用MySQL作为数据库。为了避免在大量搜索后出现“OutOfMemoryError”,我有两个选择:一个使用LIMIT(特定于数据库),另一个使用jdbc fetchSize属性。

我已经测试了选项1(LIMIT)它正在运行,但它不是理想的解决方案。我不想这样做。

使用jdbc我发现默认情况下ResultSet大小设置为0。如何将其更改为其他值。我尝试了以下方法:

a)首先尝试:

rs = preparedStatement.executeQuery();
rs.setFetchSize(1000);  //Not possible as exception occurs before.

b)秒T即使不存在,我也需要与数据库通信多个时间:

rs.setFetchSize(1000);  //Null pointer exception(rs is null).
rs = preparedStatement.executeQuery();

c)第三次尝试:

preparedStatement = dbConnection.createStatement(query);
preparedStatement.setFetchSize(1000);

这些都不起作用。任何帮助表示赞赏!

修改

我不希望使用限制的解决方案,因为: a)我的结果集中有数百万行。现在做多个查询很慢。我的假设是数据库需要多个查询,如

SELECT *  FROM a LIMIT 0, 1000
SELECT *  FROM a LIMIT 1000, 2000

作为两个不同的查询。

b)代码看起来很乱,因为你需要有额外的计数器。

3 个答案:

答案 0 :(得分:8)

MySQL JDBC驱动程序始终提取所有行,除非提取大小设置为Integer.MIN_VALUE

请参阅MySQL Connector/J JDBC API Implementation Notes

  

默认情况下,ResultSet完全检索并存储在内存中。   在大多数情况下,这是最有效的操作方式,并且由于   MySQL网络协议的设计更容易实现。如果   您正在使用具有大量行数的ResultSet   大值,并且无法在JVM中为堆空间分配堆空间   需要内存,您可以告诉驱动程序返回结果   一次一行。

     

要启用此功能,请在中创建一个Statement实例   以下方式:

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

只进,只读结果集与获取的组合   Integer.MIN_VALUE的大小用作驱动程序要流式传输的信号   结果逐行设置。在此之后,使用。创建的任何结果集   语句将逐行检索。

答案 1 :(得分:0)

除此之外,你应该改变你的查询,如

SELECT * FROM RandomStones LIMIT 1000;

或者

PreparedStatement stmt = connection.prepareStatement(qry);
stmt.setFetchSize(1000);
stmt.executeQuery();
  

要设置查询的提取大小,请在执行查询之前在语句对象上调用setFetchSize()。如果将获取大小设置为N,则每次访问数据库时都会获取N行。

答案 2 :(得分:0)

MySQL connector-j 5.1 implementation notes中,他们说有两种方法可以处理这种情况。

enter image description here

第一种是使语句逐行检索数据,第二种可以支持批量检索。