Java JDBC忽略setFetchSize?

我正在使用以下代码

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服务器)

尝试关闭自动提交:

 // 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"); 

参考

这两个查询完全不同。

使用LIMIT子句将结果集的大小限制为10000,而设置提取大小则不然,它反过来给驱动程序一个提示,说明在迭代结果集时一次要获取多少行 – 包括所有800k行。

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

为清晰起见进行编辑:除非您遍历结果(请参阅Jon的注释),否则设置获取大小不会做任何事情,但通过LIMIT创建更小的结果集会产生很大的不同。

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

为JDBC驱动程序提供有关在需要更多行时应从数据库中提取的行数的提示。 指定的行数仅影响使用此语句创建的结果集。 如果指定的值为零,则忽略提示。 默认值为零。

请注意,它表示“一个提示” – 我会认为这意味着如果一个驱动程序真的想要……就会忽略该提示……这听起来就像是发生了什么。

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

尝试按此顺序传递参数

  ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY, ResultSet.FETCH_FORWARD