【问题标题】:Efficient way to go over result set in Java在 Java 中检查结果集的有效方法
【发布时间】:2011-11-21 10:40:54
【问题描述】:

我正在运行一个选择命令,该命令返回 1,000,000 行迭代 ResultSet。下面的代码执行需要 5 分钟。

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

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

java中有没有办法在遍历结果集中的所有记录时提高效率。

谢谢

【问题讨论】:

  • 你可以让数据库使用存储过程或类似的东西来执行逻辑。
  • 为什么要选择1000000 行到内存中?
  • 在不知道您要达到什么目标的情况下回答这个问题是不可能的。您发布的代码选择了大量行,然后对它们进行迭代,什么也不做。让我们知道您要做什么,然后您会得到一些帮助。
  • 如果直接在 DB 中执行相同的查询,会不会更快?

标签: java


【解决方案1】:

您可以使用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 Guide

【讨论】:

  • 感谢 setFetchSize 提高性能
  • 干杯,如果您对答案感到满意,如果您接受,则表示感谢;)
【解决方案2】:

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

【讨论】:

    【解决方案3】:

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

    【讨论】:

      【解决方案4】:

      确保您使用的是池连接。

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

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

      你对这些数据做了什么?您真的需要一次加载所有数据吗?

      【讨论】:

        猜你喜欢
        • 2013-07-11
        • 1970-01-01
        • 2012-08-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-10-21
        • 1970-01-01
        • 2021-10-07
        相关资源
        最近更新 更多