Java JDBC忽略setFetchSize?

时间:2009-09-23 19:12:24

标签: java postgresql jdbc cursor

我正在使用以下代码

 st = connection.createStatement(
            ResultSet.CONCUR_READ_ONLY,
            ResultSet.FETCH_FORWARD,
            ResultSet.TYPE_FORWARD_ONLY
             );
 st.setFetchSize(1000);
 System.out.println("start query ");
 rs = st.executeQuery(queryString);
 System.out.println("done query");

查询返回大量(800k)行,并且在打印“开始查询”和“完成查询”之间需要很长时间(~2m)。当我在查询中手动设置“限制10000”时,“开始”和“完成”之间没有时间。处理结果需要花费时间,所以如果它只是从数据库中获取1k行,处理这些行,并且当它用完行时它可以在后台获得新行,我认为它总体上更快。

结果集.CONCUR_READ_ONLY等我最后猜测的地方;我错过了什么吗?

(这是一个postgresql 8.3服务器)

5 个答案:

答案 0 :(得分:22)

尝试关闭自动提交功能:

// make sure autocommit is off
connection.setAutoCommit(false);

 st = connection.createStatement();
 st.setFetchSize(1000);
 System.out.println("start query ");
 rs = st.executeQuery(queryString);
 System.out.println("done query");

Reference

答案 1 :(得分:2)

这取决于您的司机。来自文档:

  

给JDBC驱动程序一个提示   应该获取的行数   从更多行的数据库   需要。指定的行数   仅影响使用创建的结果集   这个说法。如果指定的值   为零,然后忽略提示。该   默认值为零。

请注意,它表示“一个提示” - 我会认为这意味着如果驾驶员真的想要这样做,就会忽略该提示......而这听起来就像是发生了什么。

答案 2 :(得分:2)

这两个查询完全不同。

使用LIMIT子句将结果集的大小限制为10000,而设置提取大小则没有,而是提示驱动程序说明一次要提取多少行迭代结果集 - 包括所有800k行。

因此,当使用setFetchSize时,数据库会创建完整的结果集,这就是它花费这么长时间的原因。

为清晰起见编辑 除非你遍历结果(参见Jon的注释),否则设置获取大小什么都不做,但是通过LIMIT创建一个小得多的结果集会产生很大的不同。

答案 3 :(得分:2)

我注意到您对API的使用与Javadoc所表达的不同:

尝试按此顺序传递参数

  ResultSet.TYPE_FORWARD_ONLY,
  ResultSet.CONCUR_READ_ONLY,
  ResultSet.FETCH_FORWARD

答案 4 :(得分:0)

我认为setFetchSize(...)是为了提供Pagenation

但是,如果您只想限制行数,请改用此方法:

st.setMaxRows(1000);