同事在公司論壇里面發(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