使用LINQ2SQL插入大量记录

时间:2009-06-10 10:55:45

标签: c# sql sql-server linq-to-sql .net-3.5

我们有一个小的c#工具,我们一起解析数据文件,构建一些对象并将它们插入到数据库中。

逻辑本质上是。

string [] lines = File.ReadAllLines("C:\\Temp\\Data.dat")

foreach(string line in lines)
{
    MyDataObject obj = ParseObject(line);
    myDataContext.MyDataObjects.InsertOnSubmit(obj);
}

myDataContext.SubmitChanges();

一开始这很好,因为数据文件每天只有大约1000行 但是最近这个文件已经增长到大约30,000行,而且这个过程变得非常缓慢。

SubmitChanges()调用的所有内容都可以,但一旦开始转储过程 DB上有30,000个插入,只是停止了。作为一项测试,我发了30,000个插入语句并直接从QA运行。花了大约8分钟。

8分钟后,C#/ Linq版本只完成了大约25%的插页。

有人建议我如何优化这个吗?

5 个答案:

答案 0 :(得分:6)

如果您要编写大量同类数据,SqlBulkCopy可能是更合适的工具,例如,可能需要CsvReader来读取行(因为SqlBulkCopy可以接受{{} 1}},这意味着您不必将所有30k行缓冲到内存中。

如果数据是CSV,则可以这么简单:

IDataReader

如果数据更复杂(非CSV),则SimpleDataReader可能有用 - 您只需将其子类化并添加代码以表示每行的数据。

答案 1 :(得分:1)

前段时间我有同样的问题。我在数据库中插入1000000个新条目,我发现每500个调用SubmitChanges是最快的方式。

我不能保证当时500排是最快的,我们的环境很奇怪......

答案 2 :(得分:1)

您可能想尝试多线程方法。

  1. 将记录集分区为较小的大小(每个1000个?),将它们放入堆栈
  2. 有一个类将从堆栈顶部获取记录集,并开始使用多线程类插入它,该类打开DataContext并自行插入。
  3. 插入时,会为下一组记录打开第二个类
  4. 内部逻辑指示一次可以运行多少个插入(5?10?)
  5. 这可能允许插入比仅仅每隔几条记录运行SubmitChanges()更快,因为多个插入可以同时发生。

答案 3 :(得分:1)

这是一项数据库任务,应该通过SSIS并使用批量插入来完成。

我可以在几秒或几毫秒内插入30,000条记录(具体取决于列数和数据映射的复杂程度)。我拥有超过一百万条记录的导入,这些记录的插入时间比您每次循环读取一条记录的时间短。我甚至有一个2000万的记录文件只需要16分钟。

答案 4 :(得分:0)

老问题,但在寻找我自己的解决方案之后,我遇到了this code project article,这非常好。基本上使用Linq2Sql属性来构建DataTable,然后使用SQLBulkCopy进行插入,这比基本的Linq2Sql实现要快得多。文章中的代码可能会使用一些清理,并且可能会在使用外键的更复杂的场景中出现(我的模型中没有任何内容,尽管在数据库中有)但完全符合我的需求。