[英]Using LINQ2SQL to insert a large number of records
我们有一个小的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()
调用的所有内容都可以,但是一旦它开始向数据库转储30,000个插入的过程,它就会停止运行。 作为一项测试,我发了30,000个插入语句并直接从QA运行。 花了大约8分钟。
8分钟后,C#/ Linq版本仅完成了大约25%的插入。
有人建议我如何优化这个吗?
如果您正在编写大量的同类数据, SqlBulkCopy
可能是一个更合适的工具,例如可能使用CsvReader
读取行(因为SqlBulkCopy
可以接受IDataReader
,这意味着您不必将所有30k行缓冲到内存中) 。
如果数据是CSV,则可以这样简单:
using (CsvReader reader = new CsvReader(path))
using (SqlBulkCopy bcp = new SqlBulkCopy(CONNECTION_STRING))
{
bcp.DestinationTableName = "SomeTable";
bcp.WriteToServer(reader);
}
如果数据更复杂(不是CSV),则SimpleDataReader
可能很有用 - 您只需将其子类化并添加代码以表示每行的数据。
我前段时间有同样的问题。 我在数据库中插入1000000个新条目,我发现每500个调用SubmitChanges是最快的方法。
我不能保证当时500排是最快的,我们的环境很奇怪......
您可能想尝试多线程方法。
这可能允许插入比仅仅每隔几条记录运行SubmitChanges()更快地进行,因为多个插入可以同时发生。
这是一个数据库任务,应该通过SSIS并使用批量插入来完成。
我可以在几秒或几毫秒内插入30,000条记录(取决于列数和数据映射的复杂程度)。 我拥有超过一百万条记录的导入,这些记录的插入时间比您每次循环读取一条记录的时间短。 我甚至有一个2000万的记录文件,只需要16分钟。
老问题,但在寻找我自己的解决方案之后,我遇到了这个代码项目文章非常好。 基本上使用Linq2Sql属性来构建DataTable,然后使用SQLBulkCopy进行插入,这比基本的Linq2Sql实现要快得多。 文章中的代码可能会使用一些清理,并且可能会在使用外键的更复杂场景中出现(我的模型中没有任何内容,尽管在数据库中有)但完全符合我的需求。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.