2010-08-11 64 views
1

我有幾個XML文件,每個文件都包含'根對象'的數據,我使用Linq解析XML,然後創建實際的根對象,我堅持使用NHibernate和尖銳的架構庫。我已經開始優化數據插入,並在大約1小時40分鐘內向數據庫中添加30000個對象。但是,這仍然太慢。NHibernate插入/查找性能

我認爲一個瓶頸就是數據庫中需要IO的對象查找。對象必須查找重用。

根對象有幾個作者:

public virtual IList<Author> Authors { get; set; } 

作者有這樣的結構:

public class Author : Entity 
    { 
public virtual Initials Initials { get; set; } 
     public virtual ForeName ForeName { get; set; } 
     public virtual LastName LastName { get; set; } 
    } 

我以一個類型ID(這是我通常不會做取得了巨大的加速):

public class LastName : EntityWithTypedId<string>, IHasAssignedId<string> 
    { 
     public LastName() 
     { 
     } 
     public LastName(string Id) 
     { 
      SetAssignedIdTo(Id); 
     } 
     public virtual void SetAssignedIdTo(string assignedId) 
     { 
      Id = assignedId; 
     } 
    } 

我仰望(可能創建)像這樣:

LastName LastName = LastNameRepository.Get(TLastName); 

         if (LastName == null) 
         { 
          LastName = LastNameRepository.Save(new LastName(TLastName)); 
          LastNameRepository.DbContext.CommitChanges(); 
         } 
         Author.LastName = LastName; 

我期待作家像這樣:

propertyValues = new Dictionary<string, object>();    
propertyValues.Add("Initials", Author.Initials); 
        propertyValues.Add("ForeName", Author.ForeName); 
        propertyValues.Add("LastName", Author.LastName); 
        Author TAuthor = AuthorRepository.FindOne(propertyValues); 

        if (TAuthor == null) 
        { 
         AuthorRepository.SaveOrUpdate(Author); 
         AuthorRepository.DbContext.CommitChanges(); 
         Root.Authors.Add(Author); 
        } 
        else 
        { 
         Root.Authors.Add(TAuthor); 
        } 

我能提高嗎?我應該使用存儲過程/ HQL /純SQL/ICriteria來執行查找嗎?我可以使用某種形式的緩存來加速查找並減少IO嗎? CommitChanges似乎是必要的,或者我應該把所有事情都包含在交易中?

我已經每10個根對象刷新會話等。

任何反饋將非常歡迎。提前謝謝了。

最良好的祝願,

基督教

回答

1

在所有誠實中,我會說,你甚至不應該使用SA/NHibernate這樣的東西。這是從XML導入的大量數據 - 像SSIS這樣的ETL工具將是更好的選擇。即使DB服務器上的手動過程也會更好 - 第1步,將XML加載到表中,第2步執行UPSERT。順便提一句,SQL 2008引入了用於UPSERT操作的MERGE命令,這可能是有用的。

我也同意丹的評論 - 是否真的有必要將首字母,姓氏和姓氏作爲單獨的實體處理?將它們視爲簡單的字符串可以提高性能。您的域模型中的哪些內容指定它們本身就是實體?

如果你真的必須繼續使用SA/NHibernate的,有這樣一個閱讀: http://www.lostechies.com/blogs/jimmy_bogard/archive/2010/06/24/bulk-processing-with-nhibernate.aspx

在吉米的有關配料的SELECT博客的建議應該幫助不少。如果您計劃一次處理一批250條記錄,請將所有SELECT作爲單個NH命令,處理所有數據,然後將所有更新作爲另一批次處理(我相信您使用的是EntityWithTypedId和adonet.batch_size配置設置將有助於實現)

最後 - 關於「我使用Linq解析XML」的聲明 - 是否真的是這樣做的最佳方式?鑑於輸入文件的大小,我猜測它可能是這樣的,但是你是否知道簡單地將XML文件反序列化爲對象圖的方法?因此,我不會讓鏈接發佈到描述該頁面的頁面,因爲我還沒有獲得足夠的聲譽 - 但是如果您想閱讀它,Google「不會解析該xml」,第一篇文章將解釋它。

希望這會有所幫助。 Jon

+0

我結束了使用xsd2code。請確保如果您的xml包含dtd信息,請使用:BlaClassBlaClass =((BlaClass)(serializer.Deserialize(System.Xml.XmlReader.Create(new XmlTextReader(filepath),new System.Xml.XmlReaderSettings(){ProhibitDtd = false })))); – cs0815 2010-08-16 09:49:37

0

我會做的第一件事是簡化作者實體,我不認爲你需要的縮寫,名,並作爲獨立的實體名字的對象。我認爲使用簡單的字符串會更有效率:

public class Author : Entity 
{ 
    public virtual string Initials { get; set; } 
    public virtual string ForeName { get; set; } 
    public virtual string LastName { get; set; } 
} 
+0

感謝 - 這是我嘗試使用lookuptables查找名稱時的其餘部分 - 我使用int而不是實際字符串作爲主鍵。然後我意識到int的查找花費了很多時間 - 所以我用內存支付了插入效率。 – cs0815 2010-08-12 08:11:33