Linq2sql 更新一个巨大的表中的每一行

本文关键字:一行 一个 更新 Linq2sql 巨大 | 更新日期: 2023-09-27 18:32:28

我有一个巨大的表(超过80M行),我使用linq2sql从数据库创建了一个模型。我遍历表(所有 80M 行)并用几个值更新每一行。我已经做了最多的来优化linq2sql代码周围的代码,但看起来db.SaveChanges()方法在第一次更新时挂起。

我的代码看起来像这样(我正在解释可读性):

using(MessageListCtx db = new MessageListCtx())
{
   foreach(var message in db.MessageList.OrderByDescending(e => e.RecordId))
   {
      message.hashCode = Hasher.GenerateHash(message.name);
      db.SubmitChanges();
   }
}

我猜问题是当我调用db.SubmitChanges();上下文中的所有对象都会迭代更改时,这对于超过 80M 的对象需要一段时间,但我不知道如何解决这个问题。

我正在考虑使用 for 循环对结果进行分页。像这样:db.MessageList.Skip(i).Take(1000).但我宁愿采用开箱即用的解决方案,如果存在的话。有人可以指出我正确的方向吗?

Linq2sql 更新一个巨大的表中的每一行

算了

Linq 2sql 不是为批处理操作而设计的。您确实需要将其移动到设定的操作级别才能获得一些性能。

无论您做什么,您都会获得单独的更新语句,因此没有性能。

我想最快的方法是做这样的事情:

  • 使用不带更改跟踪的 Foreach ( ObjectTrackingEnabled = false

  • 使用哈希构建内存中数据结构

  • 使用 SQLBULKCOPY 将大容量插入到临时表中 (http://msdn.microsoft.com/en-US/library/System.data.sqlclient.sqlbulkcopy(v=vs.110).aspx)

  • 使用"老式"更新语句更新大表

我想仍然使用这种方法,您可能希望一次将其缓冲为 100k 条记录

性能不佳来自被跟踪的大量对象。这需要删除。

请尝试以下操作:

  • 使用一个上下文读取记录,无需状态跟踪
  • 使用单独的写入上下文编写每个更新,并在调用 SaveChanges 之前将实体附加到该更新