日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

两种极端情况的案例:N+1次查询和笛卡尔积

發布時間:2025/3/15 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 两种极端情况的案例:N+1次查询和笛卡尔积 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

2019獨角獸企業重金招聘Python工程師標準>>>

前一篇文章兩種極端:頻繁的查詢和巨大的結果集講到了Hibernate加載數據時可能會出現的兩種極端情況:頻繁的查詢和一次查出巨大的結果集。其中:N+1次查詢是前一種情況的一個典型案例,笛卡爾積則是后一種情況的典型案例。下面分別簡單地再總結一下這兩種極端案例出現的原因以及調優方法。

?

一.N+1次查詢

??? 如果一個集合是lazy loading的,那么在第一次訪問到這個集合時,hibernate會生成一個select被這個集合加載出來。這是N+1中的1。緊接著,在迭代這個集合的過程中,如果要訪問集合元素所依賴的其他關聯對象時,若它的關聯對象也是lazy loading的,那么hibernate會生成一個select從數據庫中加載出這個關聯對象。這樣,N次循環就會生成n個select,這就是N+1中的N.

??? 解決N+1次查詢需要在制定動態抓取策略時eager fetch出集合和集合元素的依賴對象,這樣只會生成一條SQL。具體做法是在HOL中,使用fetch關鍵字來抓取所需要的對象。在Criteria中使用setFetchMode方法設置目標抓取對象。具體示例請參考JPwH-13.5.2

?

?

二.笛卡爾積

??? N+1次查詢的反面就是笛卡爾積。一般來說,通過定制動態抓取策略,不會加載出我們不需要的數據,但是有一種情況下,即使我們只加載必需對象也會造成大量數據被select出來,這就是抓取“平行”集合導致的笛卡爾積。

??? 例如:一個Forum有一個Moderator集合,大小為3和一個Thread集合,大小為100。如果在加載Forum時,單獨抓取Moderator集合,結果集是3,單獨抓取Thread集合,結果集是100,同時抓取這兩個集合的結果集是兩個集合的加乘(也就是笛卡爾積)為:3*100.如果還有第三個集合,大小是50的話,那結果集就會變成3*100*50.?因此我們可以看到:抓取“平行”集合會產生笛卡爾積,如果集合很多或集合中的元素很多,會使結果集急劇的膨脹。一個巨大的結果集所帶來的性能損失是什么呢?想想數據庫服務器處理這個條數據所花的時間,占用的服務器的內存,通過網絡傳輸這些數據,以即到了應用服務器占用的內存和hibernate封裝這些數據所花費的時間,和這些開銷相比,分成兩三個SQL(會成數量級的減小結果集)來獲取數據要快得多得多。

??? HIbernate并不禁止我們產生笛卡爾積,也就是說,你可以在一個抓取計劃中抓取多個“平行”集合。但是有一個例外,就是bag集合。Hibernate不允許同時抓取兩個以上的bag集合。這是因為:The resultset of a product can’t be converted into bag collections, because Hibernate can’t know which rows contain duplicates that are valid (bags allow duplicates) and which aren’t.

??? 對于“平行”集合的問題,在抓取時要靈活應對,如果預計到結果集會很大,那么就不要使用join fetch,而要使用subselect fetch!subselect fetch是平行集合的推薦優化方案。

??? 關于N+1次查詢和笛卡爾積,請參考JPwH_13.2.5節。

?

?

?

?

???

?

?

?

轉載于:https://my.oschina.net/pangzhuzhu/blog/326989

總結

以上是生活随笔為你收集整理的两种极端情况的案例:N+1次查询和笛卡尔积的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。