<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    隨筆-46  評論-54  文章-0  trackbacks-0

    同事在公司論壇里面發的,其實是我接手的一個項目中存在這個問題。
    在使用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.javaeye.com/blog/38481
    對幾種游標類型做了介紹,并給出了建議

    posted on 2008-05-28 11:26 rox 閱讀(4199) 評論(4)  編輯  收藏 所屬分類: hibernate

    評論:
    # re: 開發者請注意oracle jdbc的resultSet.last()方法的效率問題【轉載】 2008-08-05 20:55 | tykon
    謝了。  回復  更多評論
      
    # re: 開發者請注意oracle jdbc的resultSet.last()方法的效率問題【轉載】 2008-08-20 15:11 | hello
    非常好,謝謝  回復  更多評論
      
    # re: 開發者請注意oracle jdbc的resultSet.last()方法的效率問題【轉載】 2009-03-12 17:27 | javakaifa
    解決方法是什么?  回復  更多評論
      
    # re: 開發者請注意oracle jdbc的resultSet.last()方法的效率問題【轉載】 2009-03-20 12:08 | rox
    @javakaifa
    HibernatePage
    http://www.hibernate.org/248.html

    protected static HibernatePage getScrollPageInstanceWithTotalByScroll(Query query, int pageNumber, int pageSize){
    ...
    sp.scrollableResults.last();
    sp.totalElements = sp.scrollableResults.getRowNumber();
    ...
    }
    追加一個方法,參數中支持把總數作為參數傳進來。
    protected static HibernatePage getScrollPageInstanceWithTotalByScroll(Query query, Integer totalCount, int pageNumber, int pageSize){
    ...
    if (totalCount != null)
    sp.totalElements = totalCount.intValue();
    else {
    sp.scrollableResults.last();
    sp.totalElements = sp.scrollableResults.getRowNumber();
    }
    ...
    }
    這個totalCount,使用相同查詢條件,只是查詢中使用count(*)來計算結果,并賦值給totalCount。
    也就是說同樣一個查詢,要做兩遍,一個是count,先做,再一個才是查詢。  回復  更多評論
      
    主站蜘蛛池模板: 亚洲熟妇无码八AV在线播放| 成人精品视频99在线观看免费| 亚洲日韩精品A∨片无码| 18禁超污无遮挡无码免费网站国产| 你好老叔电影观看免费| 羞羞漫画在线成人漫画阅读免费| 亚洲视频在线不卡| 久久亚洲高清观看| 亚洲一本大道无码av天堂| 日本免费一区二区三区最新| 国产免费一区二区三区| 美女视频黄a视频全免费网站色窝 美女被cao网站免费看在线看 | 国产三级在线观看免费| 中文字幕天天躁日日躁狠狠躁免费| 黄色网站软件app在线观看免费 | 国产精品成人免费一区二区 | 亚洲人成综合在线播放| 亚洲国产一区在线| 国产亚洲婷婷香蕉久久精品| 亚洲乱码中文字幕综合234| 免费国产小视频在线观看| 日本无吗免费一二区| 国内一级一级毛片a免费| 中文字幕无码视频手机免费看 | 亚洲v高清理论电影| 亚洲国产另类久久久精品黑人 | 一个人看的在线免费视频| 黄色三级三级三级免费看| 久久亚洲色WWW成人欧美| 亚洲欧美精品午睡沙发| 亚洲精品国产第一综合99久久| 亚洲欧美日韩久久精品| jizzjizz亚洲日本少妇| 国产精品亚洲专一区二区三区| 国产精品亚洲精品久久精品| 久久亚洲精品11p| 五月天婷婷精品免费视频| 久久国产乱子伦精品免费午夜| 丝瓜app免费下载网址进入ios| 四虎国产精品免费永久在线| 国产精品免费看久久久|