消極式載入(Lazy Loading)是啥玩意兒?估計地球人都知道,它的意義在於只在需要的時候才去載入必要的資料,這樣可以避免即時載入所帶來的不必要的系統開銷(教科書是這麼說的)。另外,教科書中還舉了個例子。例如某個User對象在載入時會同時讀取其所關聯的多個地址(Address)對象,對於需要對Address進行操作的應用來說,關聯資料的自動載入機制非常有效。不過呢如果我們只想要獲得User的性別(sex)屬性,而不關心User的地址(Address)資訊,那麼載入Address的特性就顯得多餘,並且造成了極大的效能浪費。為了獲得User的性別屬性,我們可能還要同時從資料庫中讀取數條無用的地址資料,這導致了大量無謂的系統開銷,因此消極式載入就這麼閃亮登場,基本上目前絕大多數的ORM都具有消極式載入的特性。
好處如此多,為啥要慎用?
第一,消極式載入搞不好就容易導致N+1 select問題,效能反而不能保障
第二,消極式載入一般是在ORM中採用位元組碼增強方式來實現,這種方式處理後的對象往往會導致對象序列化失效,而在大型web應用中一般都會採用 獨立的緩衝架構,一但應用系統引入獨立的緩衝系統對應用資料對象進行緩衝,採用消極式載入後的對象序列化將失效,導致緩衝失敗。
第三,ORM中的消極式載入將業務對象的載入關係搞得不清不楚,如果某天想換ORM,那麼還得針對不同的ORM處理消極式載入關係,即使不還ORM後來人想理解載入關係也會很頭疼。
第四,消極式載入目的是一方面是對了使應用只載入必要的資料,減少資料轉送量,提高查詢速度。另一方面,為了減輕資料庫的進行不必要查詢而進行運行增加的壓力,避免一次性進行過多的查詢,減少系統消耗。對於第一個問題,通過必要的緩衝一般可以解決,對於這點系統消耗一般還是可以承受;對於第二個問題,通過在業務層進行單表查詢配合必要的索引一般也是不存在問題的。
第五,從另外一方面考慮,ORM需要承擔的僅僅是O R M,和事務、緩衝等特性一樣,它們應該由其他更有資格的傢伙來承擔,不需要搞那麼負載,否則對於以後的底層擴充,那可是一個艱巨的工作。
建議,沒有必要不要使用ORM中消極式載入特性,除非你的系統效能實在是不行了,需要消極式載入來避免這類系統消耗,那時你再考慮使用。而即使你要使用消極式載入特性,也建議你考慮清楚,是否要增加獨立的應用緩衝等等,有時可能根本原因在於系統的設計問題。