开发者请注意oracle jdbc的resultSet.last()方法的效率问题

在使用Hibernate分页器时,习惯使用直接把查询语句、页数、分页大小,传给分页器,这样会默认使用last来获取总记录数,效率非常的低。
解决方法,很简单,就是用SQL来count查询条件获得总记录的Query,再给Hibernate分页器(本身就写好了的)。
这样就必须多写几行代码,就是因为自己懒,觉着效果都一样,就简单的写了。
数据量大了以后,就很明显的速度慢下来了。又全部重头改过,很是郁闷。
转载此文,以示提醒!
即使懒得研究Hibernate底层,也要注意它的效率问题。

 

 

我看到一些资料这样说,oracle的jdbc驱动是不支持服务器端的游标的,当你调用resultSet.last()时,jdbc驱动程序会把整个结果集的数据读到内存,然后在内存中进行结果集的遍历。

如果在做分页的时候,用这样的方式获取结果的总记录数:
  rs.last();
  int rowcount = rs.getRow();
在结果集很大的时候,这个性能是相当低下的,并且会用掉很多的内存。

这个问题是昨天在检查人才网的代码时发现的,随着数据增加,原来被掩盖的问题才开始暴露出来。我们用jprofiler对程序进行剖析的情况也间接的证明了上面的说法:1) 连续几次刷新工作列表后,虚拟机的内存被占满了,运行垃圾回收后内存又被释放出来。2) 从页面请求到完成响应,resultSet.last()方法的调用占去了cpu的绝大部分时间。

因为上面提到的分页方法是一种常用的方法,我建议大家考虑一下自己的代码是否存在这样的问题,这对办公系统的稳定运行可能是很重要的。


参考:
http://www.oracle.com/technology/global/cn/sample_code/tech/java/codesnippet/jdbc/rs/CountResult.html
提到了:
如果 ResultSet 非常大,则 resultset.last() 有可能是非常费时的操作,因为它将使用服务器端的更多资源。因此,除非确实需要可滚动结果集,应避免使用这种方法。

http://forum.springframework.org/showthread.php?t=50044&page=2
提到了:
Anyway, if it's a normal behaviour of the oracle driver to keep data in memory when using SCROLLABLE resultset

http://xiongbo.iteye.com/blog/38481
对几种游标类型做了介绍,并给出了建议

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值