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

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

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

    隨筆-46  評(píng)論-54  文章-0  trackbacks-0

    同事在公司論壇里面發(fā)的,其實(shí)是我接手的一個(gè)項(xiàng)目中存在這個(gè)問題。
    在使用Hibernate分頁器時(shí),習(xí)慣使用直接把查詢語句、頁數(shù)、分頁大小,傳給分頁器,這樣會(huì)默認(rèn)使用last來獲取總記錄數(shù),效率非常的低。
    解決方法,很簡(jiǎn)單,就是用SQL來count查詢條件獲得總記錄的Query,再給Hibernate分頁器(本身就寫好了的)。
    這樣就必須多寫幾行代碼,就是因?yàn)樽约簯校X著效果都一樣,就簡(jiǎn)單的寫了。
    數(shù)據(jù)量大了以后,就很明顯的速度慢下來了。又全部重頭改過,很是郁悶。
    轉(zhuǎn)載此文,以示提醒!
    即使懶得研究Hibernate底層,也要注意它的效率問題。

     

     

    我看到一些資料這樣說,oracle的jdbc驅(qū)動(dòng)是不支持服務(wù)器端的游標(biāo)的,當(dāng)你調(diào)用resultSet.last()時(shí),jdbc驅(qū)動(dòng)程序會(huì)把整個(gè)結(jié)果集的數(shù)據(jù)讀到內(nèi)存,然后在內(nèi)存中進(jìn)行結(jié)果集的遍歷。

    如果在做分頁的時(shí)候,用這樣的方式獲取結(jié)果的總記錄數(shù):
      rs.last();
      int rowcount = rs.getRow();
    在結(jié)果集很大的時(shí)候,這個(gè)性能是相當(dāng)?shù)拖碌?,并且?huì)用掉很多的內(nèi)存。

    這個(gè)問題是昨天在檢查人才網(wǎng)的代碼時(shí)發(fā)現(xiàn)的,隨著數(shù)據(jù)增加,原來被掩蓋的問題才開始暴露出來。我們用jprofiler對(duì)程序進(jìn)行剖析的情況也間接的證明了上面的說法:1) 連續(xù)幾次刷新工作列表后,虛擬機(jī)的內(nèi)存被占滿了,運(yùn)行垃圾回收后內(nèi)存又被釋放出來。2) 從頁面請(qǐng)求到完成響應(yīng),resultSet.last()方法的調(diào)用占去了cpu的絕大部分時(shí)間。

    因?yàn)樯厦嫣岬降姆猪摲椒ㄊ且环N常用的方法,我建議大家考慮一下自己的代碼是否存在這樣的問題,這對(duì)辦公系統(tǒng)的穩(wěn)定運(yùn)行可能是很重要的。


    參考:
    http://www.oracle.com/technology/global/cn/sample_code/tech/java/codesnippet/jdbc/rs/CountResult.html
    提到了:
    如果 ResultSet 非常大,則 resultset.last() 有可能是非常費(fèi)時(shí)的操作,因?yàn)樗鼘⑹褂梅?wù)器端的更多資源。因此,除非確實(shí)需要可滾動(dòng)結(jié)果集,應(yīng)避免使用這種方法。

    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
    對(duì)幾種游標(biāo)類型做了介紹,并給出了建議

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

    評(píng)論:
    # re: 開發(fā)者請(qǐng)注意oracle jdbc的resultSet.last()方法的效率問題【轉(zhuǎn)載】 2008-08-05 20:55 | tykon
    謝了。  回復(fù)  更多評(píng)論
      
    # re: 開發(fā)者請(qǐng)注意oracle jdbc的resultSet.last()方法的效率問題【轉(zhuǎn)載】 2008-08-20 15:11 | hello
    非常好,謝謝  回復(fù)  更多評(píng)論
      
    # re: 開發(fā)者請(qǐng)注意oracle jdbc的resultSet.last()方法的效率問題【轉(zhuǎn)載】 2009-03-12 17:27 | javakaifa
    解決方法是什么?  回復(fù)  更多評(píng)論
      
    # re: 開發(fā)者請(qǐng)注意oracle jdbc的resultSet.last()方法的效率問題【轉(zhuǎn)載】 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();
    ...
    }
    追加一個(gè)方法,參數(shù)中支持把總數(shù)作為參數(shù)傳進(jìn)來。
    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();
    }
    ...
    }
    這個(gè)totalCount,使用相同查詢條件,只是查詢中使用count(*)來計(jì)算結(jié)果,并賦值給totalCount。
    也就是說同樣一個(gè)查詢,要做兩遍,一個(gè)是count,先做,再一個(gè)才是查詢。  回復(fù)  更多評(píng)論
      
    主站蜘蛛池模板: 亚洲片国产一区一级在线观看| 久久亚洲精品无码aⅴ大香| 国产性生大片免费观看性| 亚洲一级二级三级不卡| 女人张腿给男人桶视频免费版| 特级aa**毛片免费观看| 亚洲av无码不卡| 亚洲一本一道一区二区三区| 免费在线观看你懂的| 无码av免费网站| 在线a亚洲老鸭窝天堂av高清| 国产亚洲色婷婷久久99精品91| 麻豆国产精品免费视频| 免费看一级高潮毛片| 在线观看永久免费| 无人视频免费观看免费视频| 亚洲精品免费在线| 亚洲一级特黄大片在线观看| 国产精品69白浆在线观看免费| 九九热久久免费视频| 亚洲色一区二区三区四区| 亚洲女同成av人片在线观看| 免费无码又爽又刺激高潮的视频| 日韩在线永久免费播放| 无码的免费不卡毛片视频| 亚洲中文字幕无码一区二区三区| 国产黄片不卡免费| 亚洲xxxx视频| 亚洲欧洲日韩不卡| 免费人成在线视频| 怡红院亚洲红怡院在线观看| 亚洲美女视频网站| 亚洲Av无码专区国产乱码DVD| 免费v片在线观看品善网| 午夜性色一区二区三区免费不卡视频| 中文字幕一区二区三区免费视频| 亚洲国产欧美一区二区三区| 亚洲毛片免费观看| 亚洲国产第一站精品蜜芽| 亚洲福利在线播放| 老司机永久免费网站在线观看|