【疑難雜症02】ResultSet.next() 效率低下問題解決


  今天幫同事解決了一個問題,記錄一下,幫助有需要的人。

一、問題解決經過

  事情的經過是這樣的,下午我在敲代碼的時候,一個同事悄悄走到我身邊,問我有沒有用沒用過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方法有問題,你快去網上找找有沒有其他的替代方法。

  此時我心中一萬只草泥馬奔騰而過,我看過一些源碼,而且知道操作數據庫的底層都是封裝的它們,旁邊這位不僅不解決問題,還打算掩埋問題繞彎路,我想說你把我叫過來解決問題,能不能聽我的,不過我沒有這么說,因為他們兩個都是我的領導,要不是喊我過來的那個我和他關系很好,我早就回去不管了。

  不過在我的再三請求下還是給我看了SQL,我一看很長,我就說拿到PL/SQL中執行一下,結果又來否定我,說我都執行過了很快的,旁邊那位依然大聲說怎么可能是SQL問題呢,以前就用過了,我只能說我心好累,最終放到PL/SQL中執行了,結果確實是兩三秒顯示出來,他們就說你看。

  我什么也沒說,大家應該都知道PL/SQL執行后只會顯示前多少條數據,只有點向下的箭頭才會顯示所有的數據,我就讓他顯示所有的數據,因為只有1000條我想是很快的,確實剩下的飛快的顯示完,但是當顯示完1000條數據以后,執行並沒有終止,直到30多秒過去以后,才顯示執行完成,也就是說查詢出需要的1000條數據后,查詢依然進行只是沒有輸出結果。

  我說你SQL寫的有問題,結果在這種情況下,他居然還說,那剛剛那條語句怎么飛快的執行完了呢:

ResultSet rs = stmt.executeQuery(sql);

  說這條執行完了,不就把所有的結果都帶回來了嗎,說實話我沒有深入了解過,不過我猜應該是沒有帶回來,我讓他測試一下,取所有數據大約5W條,ResultSet 依然很迅速的獲取到,但是按常理是不會這么快的,結合剛才的現象猜測,ResultSet 並沒有帶回來結果集。

  然后我又看了一遍他寫的SQL,看出了問題,分頁寫錯了,我說你改好應該就沒有問題了。

二、收獲總結

2.1 我的收獲

  幫別人解決問題還是有收獲的,首先可以肯定的事是ResultSet.next() 效率低下是錯覺,真正效率低下的是寫出SQL的執行速度,同樣ResultSet只是代表着結果集,而不表示它就是整個結果集的數據,具體源碼等我有空的時候會研究並貼出。

2.2 我想說的話

  當出現奇怪的問題的時候,不要這么做:

  1. 大量重復測試
  2. 懷疑框架,懷疑Java,懷疑人生

  這兩條是很重要的,大量重復測試是大忌,浪費時間而且還容易掩蓋錯誤,一遍遍看着結果露出不可置信的眼神,第二條就是懷疑Java是不是有缺陷,框架是不是有bug,當然不可否認任何東西都不是完美的,但是相比較而言,還是首先懷疑自己比較好。把自己理所當然覺得沒問題的步驟好好看一遍,也許原因就在其中。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM