我有几个XML文件,每个文件包含“root对象”的数据,我使用Linq to XML解析,然后创建实际的根对象,我使用NHibernate和尖锐的架构存储库来保存。我已经开始优化数据插入并管理在大约1小时40分钟内向数据库添加30000个对象。但是,这仍然太慢了。
我认为一个瓶颈就是在数据库中查找需要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个根对象刷新会话等。
非常欢迎任何反馈意见。非常感谢提前。
祝福,
基督教
答案 0 :(得分:1)
老实说,我会说你甚至不应该使用SA / NHibernate这样的东西。这是从XML导入的批量数据 - 像SSIS这样的ETL工具将是更好的选择。即使数据库服务器上的手动过程也会更好 - 第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
Jimmy博客中关于批量处理SELECT的建议应该会有很多帮助。如果您计划一次处理一批250条记录,请将所有SELECT作为单个NH命令处理,处理所有数据,然后将所有更新作为另一个单一批处理(我相信您使用EntityWithTypedId和adonet.batch_size)配置设置将有助于实现)
最后 - 关于“我使用Linq to XML解析”的陈述 - 这真的是最好的方法吗?考虑到输入文件的大小,我猜它可能是,但您是否知道将XML文件反序列化为对象图的方法?所以我不会发布链接到描述这个的页面,因为我还没有获得足够的声誉 - 但如果你想阅读它,谷歌“不解析那个xml”,第一篇文章将解释它
希望这会有所帮助。 乔恩
答案 1 :(得分:0)
我要做的第一件事就是简化Authors实体,因为我认为你不需要将Initials,ForeName和LastName对象作为单独的实体。我认为使用普通字符串会更有效:
public class Author : Entity
{
public virtual string Initials { get; set; }
public virtual string ForeName { get; set; }
public virtual string LastName { get; set; }
}