我正在使用以下代码
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服务器)
答案 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");
答案 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);