在Java中高效遍历结果集的方法

4

我在运行一个选择命令,返回100万行记录并迭代ResultSet。下面的代码需要5分钟才能执行。

有没有更快的迭代ResultSet的方法?

conn = getDbConnection();
Statement createStatement = conn.createStatement();
ResultSet rs = createStatement.executeQuery("Select * from myTable");
while (rs.next())
{
    //do nothing
}

有没有一种方法可以在 Java 中更有效地处理结果集中的所有记录?
谢谢。

1
你可以使用存储过程或类似的方法让数据库执行逻辑。 - trojanfoe
2
为什么要将 1000000 行选择到内存中? - jmj
1
不知道你想要实现什么目标,所以无法回答这个问题。你发布的代码选择了大量的行,然后对它们进行迭代但什么都没做。告诉我们你想要做什么,然后你就会得到一些帮助。 - Qwerky
如果您直接在数据库中执行相同的查询,它是否会更快? - soulcheck
4个回答

12

您可以使用 setFetchSize(rows) 来优化获取数据的大小,它可以一次从数据库中获取指定数量的行。

conn = getDbConnection();
Statement createStatement = conn.createStatement();
createStatement.setFetchSize(1000);
ResultSet rs = createStatement.executeQuery(“Select * from myTable”);
while (rs.next())
{
//do nothing        
}

请注意,fetchSize只是对DB的提示,它可能会忽略这个值。只有测试才能确定它是否是最优的。

此外,在您的情况下,更改Statement的Scrollable属性可能更好,因为您可能不会一次处理所有记录。选择哪个滚动选项取决于您是否希望在迭代时看到其他人的更改。

//TYPE_FORWARD_ONLY 
//      The constant indicating the type for a ResultSet object 
//    whose cursor may move only forward.
conn.createStatement(ResultSet.TYPE_FORWARD_ONLY, 
                           ResultSet.CONCUR_READ_ONLY); 

或者

//TYPE_SCROLL_INSENSITIVE
//      The constant indicating the type for a ResultSet object that is 
//    scrollable but generally not sensitive to changes made by others.    
conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, 
                           ResultSet.CONCUR_READ_ONLY); 

或者

//TYPE_SCROLL_SENSITIVE
//      The constant indicating the type for a ResultSet object that is 
//    scrollable and generally sensitive to changes made by others.
conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, 
                           ResultSet.CONCUR_READ_ONLY); 

详见JDBC API指南以获取更详细的信息


2
感谢 setFetchSize 提高了性能。 - Blue Label
如果您对答案满意,那就太好了。如果您能接受它,我们将不胜感激。;) - Prashant Bhate

4

与其试图从数据库中提取100万行数据(无论你如何努力,都不能使其运行得更快),你应该让数据库为你工作,并返回你想要的答案而不是中间结果。尝试编写更复杂的选择查询或存储过程。


1

我认为没有更有效的方法来迭代结果集。你有检查过查询实际运行的速度吗,例如在SQLDeveloper或其他数据库工具中?我的假设是,该表没有建立索引或数据库端存在其他性能瓶颈。


1

确保您正在使用池化连接。

使用PreparedStatements也可能对性能产生积极影响。

(虽然这可能不会为您节省几分钟时间。)

您正在处理数据做什么?您真的需要一次性加载所有数据吗?


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接