Hibernate n+1問題

來源:互聯網
上載者:User

標籤:ber   details   情況   記錄   art   緩衝   通過   依次   find   

轉自:

http://www.blogjava.net/RoyPayne/archive/2012/01/30/369017.html
http://msi110.iteye.com/blog/710183
http://blog.csdn.net/xiaoxian8023/article/details/15380529

========================================================

 

在Session的緩衝中存放的是相互關聯的對象圖。預設情況下,當Hibernate從資料庫中載入Customer對象時,會同時載入所有關聯的 Order對象。以Customer和Order類為例,假定ORDERS表的CUSTOMER_ID外鍵允許為null

以下Session的find()方法用於到資料庫中檢索所有的Customer對象:

List customerLists=session.find("from Customer as c"); 

運行以上find()方法時,Hibernate將先查詢CUSTOMERS表中所有的記錄,然後根據每條記錄的ID,到ORDERS表中查詢有參照關係的記錄,Hibernate將依次執行以下select語句:

select * from CUSTOMERS; select * from ORDERS where CUSTOMER_ID=1; select * from ORDERS where CUSTOMER_ID=2; select * from ORDERS where CUSTOMER_ID=3; select * from ORDERS where CUSTOMER_ID=4; 

通過以上5條select語句,Hibernate最後載入了4個Customer對象和5個Order對象,在記憶體中形成了一幅關聯的對象圖.


Hibernate在檢索與Customer關聯的Order對象時,使用了預設的立即檢索策略。這種檢索策略存在兩大不足:
(1) select語句的數目太多,需要頻繁的訪問資料庫,會影響檢索效能。如果需要查詢n個Customer對象,那麼必須執行n+1次select查詢語 句。這就是經典的n+1次select查詢問題。這種檢索策略沒有利用SQL的串連查詢功能,例如以上5條select語句完全可以通過以下1條 select語句來完成:

select * from CUSTOMERS left outer join ORDERS on CUSTOMERS.ID=ORDERS.CUSTOMER_ID 

以上select語句使用了SQL的左外串連查詢功能,能夠在一條select語句中查詢出CUSTOMERS表的所有記錄,以及匹配的ORDERS表的記錄。 

(2)在應用邏輯只需要訪問Customer對象,而不需要訪問Order對象的場合,載入Order對象完全是多餘的操作,這些多餘的Order對象白白浪費了許多記憶體空間。 
為瞭解決以上問題,Hibernate提供了其他兩種檢索策略:延遲檢索策略和迫切左外串連檢索策略。延遲檢索策略能避免多餘載入應用程式不需要訪問的關聯對象,迫切左外串連檢索策略則充分利用了SQL的外串連查詢功能,能夠減少select語句的數目。


對資料庫訪問還是必須考慮效能問題的, 在設定了1 對多這種關係之後, 查詢就會出現傳說中的n +1 問題。 
1)1 對多,在1 方,尋找得到了n 個對象, 那麼又需要將n 個對象關聯的集合取出,於是本來的一條sql查詢變成了n +1 條 
2)多對1 ,在多方,查詢得到了m個對象,那麼也會將m個對象對應的1 方的對象取出, 也變成了m+1

怎麼解決n +1 問題? 
1)lazy=true, hibernate3開始已經預設是lazy=true了;lazy=true時不會立刻查詢關聯對象,只有當需要關聯對象(訪問其屬性,非id欄位)時才會發生查詢動作。 

2)二級緩衝, 在對象更新,刪除,添加相對於查詢要少得多時, 二級緩衝的應用將不怕n +1 問題,因為即使第一次查詢很慢,之後直接快取命中也是很快的。 
不同解決方案,不同的思路,第二條卻剛好又利用了n +1 。

3) 當然你也可以設定fetch=join(annotation : @ManyToOne() @Fetch(FetchMode.JOIN))

 


 

Hibernate n+1問題

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.