[轉]hibernate性能問題

[b][size=medium]本貼作者 xyz20003[/size][/b]

大多數反對使用hibernate的同志,張口必說hibernate有性能問題,不好調優,對DBA不友好。可從來沒有任何一個人具體指出hibernate哪裏有性能問題,爲什麼不能調優,哪方面對DBA不友好。

大家去面試過,有些同志也有面試別人的經驗,應該明白一點:務虛很容易。什麼性能啦,什麼併發啦,什麼管理啦。每個人張口都可以說出很多來,但是一旦開始玩真格的,那些沒有實際經驗的就會原型畢露了。不是我心眼壞,戴着有色眼鏡去看人,而是社會複雜,害人之心不可有,防人之心不可無。精準的批評是一種鞭策,有則改之無則加勉。關鍵在於是否存在“三人成虎”的情況呢?

讓咱們化繁爲簡吧,只問一句話:“閣下認爲hibernate有性能問題,sql無法調優。”這個想法是切身體會呢?還是以訛傳訛而來呢?如果是切身體會,那麼懇請閣下受累一下,勞煩您把出現的問題稍微詳細的描述一下,如果有可能的話,最好還能和大家稍微討論一下這個問題出現的原因,以及解決方法。

下面算是我在實際項目中遇到的一些性能出現問題的場景,以及解決的方法,想必大家用過hibernate都應該耳聞能熟了,但是爲了避免自己出現上面所說的“空口無憑”,還是斗膽拿出來獻醜了。

1.N+1
場景描述:產品product和產品分類product_category兩張表,多對一關係。查詢產品列表時,可能出現N+1問題。
解決方法:
1:使用fetch抓取,select p from Product p join fetch p.category c
2:使用map直接搜索需要的列,select new Map(p.id as id, p.name as name, p.category.name as categoryName) from Product p

2.1:1無法lazy
場景描述:申請表頭和三張申請子表是一對一關係,其中子表對主表的關聯可以實現延遲加載,主表無法延遲加載3個子表。造成每次讀取主表以後,都同時發送三個sql查詢三個子表的信息。
解決方法:一對一關係的一方無法延遲加載是hibernate本身的bug,雖然可以使用instrument解決,但是要對字節碼進行靜態加強,不如直接改成多對一關聯。

3.大批量插入數據
場景描述:導入數據過多時,一級緩存會迅速膨脹,有時導致內存溢出。
解決方法:我們用的方法是每隔一定數目(200條)就執行session.flush()和session.clear(),現在看來還是應該是用jdbc批量插入,或者應該直接導入到數據庫裏。

回過頭來看一下,平常遇到的問題,基本都是因爲N+1以及延遲加載使用的太隨意造成的,我們對二級緩存的使用也不多,只是把一些常用的數據字典一次性緩存到內存裏了。剩下的批量插入,批量更新,確實不應該依靠hibernate來解決,這時候幸好我們還有其他選擇,使用hibernate也可以滿足我們80%以上的需求。

下面就期待同仁提出實例反證了,向大家多多學習。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章