【疑难杂症02】ResultSet.next() 效率低下问题解决

  今天帮同事解决了一个问题,记录一下,帮助有须要的人。sql

1、问题解决通过

  事情的通过是这样的,下午我在敲代码的时候,一个同事悄悄走到我身边,问我有没有用没用过Oracle,这下我蒙了,难道我在他们眼中这么弱吗?不过我仍是弱弱的问了一句咋了,他说碰到一个奇怪的现象,说他用jdbc查询Oracle,而后循环取数据要30秒,我问怎么可能,他说是真的,就1000条数据,我固然不信,就说带我去看。数据库

  而后我走过去,发现他旁边还坐了一我的,我猜也在帮忙解决问题,只不过没有解决而已,我让他给我看看代码,我看了一眼,发现很简单,以下(只是示例代码,真实代码不便贴出):框架

Connection conn = getConnection();
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(sql);
long start=System.currentTimeMillis();
while(rs.next()){
    //一系列操做
}
System.out.println(System.currentTimeMillis()-start);
=========控制台输出==========
大约就是30秒以上

  我一看,这不是标准的jdbc操做吗,我都写了800遍了,怎么可能会有问题,有问题也只能是SQL问题,因而我说给我看看你的SQL,我以为你写的SQL有问题,结果他说不可能,SQL没有问题,并且我刚刚打断点一步通常走下去都很快,就是next()方法耗时30多秒的,旁边那位依然也说不多是SQL的问题,SQL都看了,而后我又说了一遍,给我看看你写的SQL,结果仍是说SQL确定没问题,旁边那位甚至说出了让我惊讶的话,他说是否是ResultSet 的next方法有问题,你快去网上找找有没有其余的替代方法。测试

  此时我心中一万只草泥马奔腾而过,我看过一些源码,并且知道操做数据库的底层都是封装的它们,旁边这位不只不解决问题,还打算掩埋问题绕弯路,我想说你把我叫过来解决问题,能不能听个人,不过我没有这么说,由于他们两个都是个人领导,要不是喊我过来的那个我和他关系很好,我早就回去无论了。spa

  不过在个人再三请求下仍是给我看了SQL,我一看很长,我就说拿到PL/SQL中执行一下,结果又来否认我,说我都执行过了很快的,旁边那位依然大声说怎么多是SQL问题呢,之前就用过了,我只能说我心好累,最终放到PL/SQL中执行了,结果确实是两三秒显示出来,他们就说你看。code

  我什么也没说,你们应该都知道PL/SQL执行后只会显示前多少条数据,只有点向下的箭头才会显示全部的数据,我就让他显示全部的数据,由于只有1000条我想是很快的,确实剩下的飞快的显示完,可是当显示完1000条数据之后,执行并无终止,直到30多秒过去之后,才显示执行完成,也就是说查询出须要的1000条数据后,查询依然进行只是没有输出结果。blog

  我说你SQL写的有问题,结果在这种状况下,他竟然还说,那刚刚那条语句怎么飞快的执行完了呢:get

ResultSet rs = stmt.executeQuery(sql);

  说这条执行完了,不就把全部的结果都带回来了吗,说实话我没有深刻了解过,不过我猜应该是没有带回来,我让他测试一下,取全部数据大约5W条,ResultSet 依然很迅速的获取到,可是按常理是不会这么快的,结合刚才的现象猜想,ResultSet 并无带回来结果集。源码

  而后我又看了一遍他写的SQL,看出了问题,分页写错了,我说你改好应该就没有问题了。io

2、收获总结

2.1 个人收获

  帮别人解决问题仍是有收获的,首先能够确定的事是ResultSet.next() 效率低下是错觉,真正效率低下的是写出SQL的执行速度,一样ResultSet只是表明着结果集,而不表示它就是整个结果集的数据,具体源码等我有空的时候会研究并贴出。

2.2 我想说的话

  当出现奇怪的问题的时候,不要这么作:

  1. 大量重复测试
  2. 怀疑框架,怀疑Java,怀疑人生

  这两条是很重要的,大量重复测试是大忌,浪费时间并且还容易掩盖错误,一遍遍看着结果露出不可置信的眼神,第二条就是怀疑Java是否是有缺陷,框架是否是有bug,固然不能否认任何东西都不是完美的,可是相比较而言,仍是首先怀疑本身比较好。把本身理所固然以为没问题的步骤好好看一遍,也许缘由就在其中。

相关文章
相关标签/搜索