java:ResultSet 迭代与 List 迭代:是不是存在性能差异
Posted
技术标签:
【中文标题】java:ResultSet 迭代与 List 迭代:是不是存在性能差异【英文标题】:java: ResultSet iteration vs List iteration : Is there a performance differencejava:ResultSet 迭代与 List 迭代:是否存在性能差异 【发布时间】:2014-09-06 20:31:53 【问题描述】:我必须制作一个报告实用程序,该实用程序从一个非常古老的大表中获取数据。我的搜索条件将一次取出一百万条记录,这些记录稍后将用于一些垃圾 IO 操作。我可以选择使用 JDBC,它会给我一个 ResultSet 或 Hibernate,它会给我 List。我想知道迭代时两者之间是否存在性能差异。
【问题讨论】:
Hibernate 将需要通过结果集来构建该列表,那么您怎么看?但是,您的查询更有可能是您应该关注的事情,而不是结果的迭代。 我在本地机器上做了一些测试,当为大量记录调用 query.list() 时,休眠确实需要很长时间。我必须想出一个更好的解决方案。 如果您将要执行的操作是合适的,您应该在迭代时执行它们(即以流方式)。这可能不合适,但比先读取内存中的所有数据然后处理它们要快。 Fastest way to iterate through large table using JDBC的可能重复 【参考方案1】:这取决于:
休眠版本 DBMS 和版本 JDBC 驱动程序和版本通常的工作原理是:如果您使用以下方式创建 Statement
s:
PreparedStatement stmt = con.prepareStatement(sql,
ResultSet.TYPE_FORWARD_ONLY,
ResultSet.CONCUR_READ_ONLY);
然后体面 DBMS / 驱动程序将流 大查询,并且内存影响将很小,代价是持有Connection
更长时间。如果你得到List
用于使用 Hibernate 进行大查询,它会尝试一次将整个结果集加载到内存中,如果 GC 启动,整个事情最好是爬行,最坏的情况是崩溃。所以对于大型结果集,JDBC 将是更好的选择。
现在,如果您实际上不介意在 Hibernate 中使用 List
,您可以使用 ScrollableResults
。请参阅this question:即使该方法不适用于该特定情况,该技术也可以在 JDBC 方法可以正常工作的每个 DBMS/驱动程序组合上正常工作(毕竟它只是一个薄上面解释的纯 JDBC 方法之上的休眠层)。而且您还可以获得 Hibernate 的 ORM 部分。
【讨论】:
称之为共同事件...我通过将结果集设置为 Type_forward 和 Concor_read 对 PreapredStatement 应用了相同的方法。我也用 StatelessSession 尝试了 ScrollableResults,但感觉就像强迫自己使用 Hibernate,所以我选择了通用 JDBC。为了避免任何内存问题,我一次获取 2 万条记录,然后执行 IO 操作。它有点慢,但消除了 OutOfMemeoyError 的风险以上是关于java:ResultSet 迭代与 List 迭代:是不是存在性能差异的主要内容,如果未能解决你的问题,请参考以下文章