如何避免与大LINQ的交易几何放缓?(How to avoid geometric slowdown

2019-09-29 06:38发布

我已经写了一些非常不错的,时髦的图书馆在LinqToSql使用。 (有一天,当我有时间去想它,我可能会使它开源... :))

无论如何,我不知道这是有关我的库或没有,但我发现,当我在一个事务中的大量改变的对象,然后调用DataContext.GetChangeSet()事情开始变得reaalllly slooowwwww 。 当我打入的代码,我发现我的计划是旋转的轮子做非常多的Equals()的改变集中的对象之间的比较。 我不能保证这是真的,但我怀疑是否有变化组N个对象,然后调用GetChangeSet()导致每个对象进行比较,以每一个其他对象等价,即在最好的(N ^ 2-N)/ 2调用Equals() ...

是的,我当然会犯的每个单独的对象,但还挺失败交易的目的。 而在我写程序,我可以有一个包含100,000个分离的项目批处理作业,所有需要提交在一起。 大约5十亿比较有。

所以,问题是:(1)是我对形势的判断是否正确? 你得到的纯的,教科书LinqToSql这种行为,或者是这个东西我图书馆在做什么? (2)是否有一个标准的/合理的解决办法,这样我可以不使程序速度较慢几何与变化集中的每个额外的对象创建我的批处理?

Answer 1:

最后,我决定重写批,使各个项目独立保存,都在一个大的交易。 换句话说,而不是:

var b = new Batch { ... };
while (addNewItems) {
  ...
  var i = new BatchItem { ... };
  b.BatchItems.Add(i);
}
b.Insert(); // that's a function in my library that calls SubmitChanges()

..你必须做这样的事情:

context.BeginTransaction(); // another one of my library functions
try {
  var b = new Batch { ... };
  b.Insert(); // save the batch record immediately
  while (addNewItems) {
    ...
    var i = new BatchItem { ... };
    b.BatchItems.Add(i);
    i.Insert(); // send the SQL on each iteration
  }
  context.CommitTransaction(); // and only commit the transaction when everything is done.
} catch {
  context.RollbackTransaction();
  throw;
}

你可以看到为什么第一个代码块仅仅是更清洁和更自然的使用,这是一个遗憾的是我得到了被迫使用第二结构...



文章来源: How to avoid geometric slowdown with large Linq transactions?