C# 使用LINQ2SQL插入大量记录

C# 使用LINQ2SQL插入大量记录,c#,sql,sql-server,linq-to-sql,.net-3.5,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); } myDataCo

我们有一个小的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行长 但最近,该文件已增长到约30000行,处理过程变得非常缓慢

SubmitChanges()
调用中的所有内容都很好,但是一旦它开始转储过程 向数据库插入30000个插入,它只是研磨停止。作为测试,我模拟了30000条insert语句,并直接从QA处运行它们。大约花了8分钟

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


有人对我如何优化这个问题有什么建议吗?

不久前我也有同样的问题。我在数据库中插入1000000个新条目,我发现tat每500次调用SubmitChanges是最快的方法


我不能保证当时的500行速度是有史以来最快的,我们的环境非常奇怪…

如果您正在编写大量同质数据,可能是一个更合适的工具,例如,可能具有读取行的功能(因为
SqlBulkCopy
可以接受
IDataReader
,这意味着您不必将所有30k行缓冲到内存中)

如果数据为CSV,则可以简单如下:

using (CsvReader reader = new CsvReader(path))
using (SqlBulkCopy bcp = new SqlBulkCopy(CONNECTION_STRING))
{
    bcp.DestinationTableName = "SomeTable";
    bcp.WriteToServer(reader);
}

如果数据更复杂(不是CSV),那么可能会很有用-您只需将其子类化并添加代码来表示每行的数据。

您可能需要尝试多线程方法

  • 将记录集划分为较小的大小(每个1000?),并将其放入堆栈中
  • 拥有一个类,该类将从堆栈顶部获取记录集,并开始使用一个多线程类插入它,该类打开DataContext并自行插入
  • 插入时,将为下一组记录打开第二个类
  • 内部逻辑决定一次可以运行多少个插入(5?10?)

  • 这可能会使插入比仅每隔几条记录运行SubmitChanges()更快,因为多个插入可能同时发生。

    这是一项数据库任务,应该通过SSI和大容量插入来完成


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

    老问题,但在寻找我自己的解决方案后,我遇到了一个非常好的解决方案。基本上使用Linq2Sql属性来构建数据表,然后使用SQLBulkCopy进行插入,这比基本的Linq2Sql实现快得多。本文中的代码可能需要一些清理,并且可能会陷入使用外键的更复杂场景中(我的模型中没有外键,但数据库中有)但是非常适合我的需要。

    我怀疑这与单个SQL命令所能包含的最大参数数有关。我相信最大参数数为2100个。如果插入4列记录,最佳值为500个左右是有意义的。Cheers Marc,沿着这条路线,在内存中建立一个数据表并传递该数据表对于BulkCopy对象。不幸的是,它不是平面CSV,在将其推送到服务器之前需要进行大量操作。谢谢。这很好。但是它不可行。对于初学者来说,它是在SQL 2000上,所以没有SSI,这是DTS领域。其次,数据从附属公司提交到我们的业务部门。我很乐意给出em是一种只需2分钟运行即可上载数据的工具,而不是让他们完全访问数据库,这样他们就可以与enterprise manager混在一起。您可以使用DTS执行此操作。然后让您的应用程序调用DTS包。或者使用大容量插入在存储的进程中执行此操作,并让您的应用程序调用该进程。