2015-07-10 56 views
0

在我的Grails應用程序我正在使用的一些技術非常興奮,但最近我遇到一些問題的表現,我會介紹我的cenario慢慢性能:Grails的AddTo就*與事件

用4M + entires
  • 一個表;
  • 我正在使用Event Bus API;
  • Grails 2.2.3;
  • MySQL DB;

當客戶端創建新房間時,也會創建一些Alloc。

pseudo-code: 
    Room { 
     hasMany = aloccs: Alloc 
    } 

看這段代碼(不是真正的代碼,但同樣平等):

@Listener(topic="topicAlocCreator") 
def alocCreator(EventMessage<Long> message) { 

    LocalDate start = new DateTime().toLocalDate() 
    LocalDate end = new DateTime().plusYears(2).plusMonths(6).toLocalDate() 
    LocalDate tmp = start 


    Room room = Room.get(message.data) 
    List channels = Channel.list 
    while(tmp.compareTo(end) <= 0) { 
     for(channel in channels) { 
      room.addToAlocs(new Aloc(0, 0, tmp.toDate(), channel)) 
     } 
     tmp = tmp.plusDays(1) 
    } 

    //end of method 
} 

此代碼工作正常,但它產生了大量的alloc的對象,並把它放在一個Hibernate會話。

什麼是使用flush來完成這項工作的正確方法?批量? - 調用方法是assync。

此代碼工作正常,直到(07/14),但在這段時間內,它很慢,比如1.30分鐘,在數據庫中插入10K的alloc;

非常感謝您的建議。

回答

2

因爲allocsSet(默認的Grails集合類型,當你定義一個hasMany關係),Grails的有整個集合加載到內存之前插入可以爲了保證唯一性發生。

查看Bert Beckwith的presentation關於使用GORM集合的性能影響。

我想你有幾個選擇。你可以用完全收集參考免除了,只是這樣定義你的類:

class Alloc { 
    Room room 
} 

class Room { 
    //no reference child Allocs 
} 

或者,你可以定義你allocs集合作爲一個袋:

在這種情況下
class Alloc { 
    static belongsTo = [room: Room] 
} 

class Room { 
    Collection allocs 
    static hasMany = [allocs: Alloc] 
} 

有沒有必要唯一性檢查和addTo...方法將不需要將每個Alloc實例加載到內存中。但是您的話負責維護自己的獨特性......

Reference

+0

我使用的是德清單,以及休眠創建我的數據庫alloc_idx,使用收藏更performatic呢? –

+1

絕對不是更好(整個集合不必從數據庫加載而不管集合類型),實際上可能更糟糕。使用Set只保證唯一性,因此Hibernate檢測到Set中添加和刪除的實例並進行相應的單個數據庫更新。該附加列用於跟蹤列表內的順序,如果打開SQL日誌記錄,您將看到Hibernate將刪除所有實例,並在訂單更改時重新插入它們,而不是更新idx列。 –

+0

事實證明,使用掌上電腦不解決這個問題,可以讓工作的事情 - 我寫了在[本博客文章(http://burtbeckwith.com/blog/?p=1029) –