今天幫同事解決了一個問題,記錄一下,幫助有須要的人。sql
事情的通過是這樣的,下午我在敲代碼的時候,一個同事悄悄走到我身邊,問我有沒有用沒用過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
幫別人解決問題仍是有收穫的,首先能夠確定的事是ResultSet.next() 效率低下是錯覺,真正效率低下的是寫出SQL的執行速度,一樣ResultSet只是表明着結果集,而不表示它就是整個結果集的數據,具體源碼等我有空的時候會研究並貼出。
當出現奇怪的問題的時候,不要這麼作:
這兩條是很重要的,大量重複測試是大忌,浪費時間並且還容易掩蓋錯誤,一遍遍看着結果露出不可置信的眼神,第二條就是懷疑Java是否是有缺陷,框架是否是有bug,固然不能否認任何東西都不是完美的,可是相比較而言,仍是首先懷疑本身比較好。把本身理所固然以爲沒問題的步驟好好看一遍,也許緣由就在其中。