我们有一个小的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%的插页。
有人建议我如何优化这个吗?
答案 0 :(得分:6)
如果您要编写大量同类数据,SqlBulkCopy
可能是更合适的工具,例如,可能需要CsvReader
来读取行(因为SqlBulkCopy
可以接受{{} 1}},这意味着您不必将所有30k行缓冲到内存中。
如果数据是CSV,则可以这么简单:
IDataReader
如果数据更复杂(非CSV),则SimpleDataReader
可能有用 - 您只需将其子类化并添加代码以表示每行的数据。
答案 1 :(得分:1)
前段时间我有同样的问题。我在数据库中插入1000000个新条目,我发现每500个调用SubmitChanges是最快的方式。
我不能保证当时500排是最快的,我们的环境很奇怪......
答案 2 :(得分:1)
您可能想尝试多线程方法。
这可能允许插入比仅仅每隔几条记录运行SubmitChanges()更快,因为多个插入可以同时发生。
答案 3 :(得分:1)
这是一项数据库任务,应该通过SSIS并使用批量插入来完成。
我可以在几秒或几毫秒内插入30,000条记录(具体取决于列数和数据映射的复杂程度)。我拥有超过一百万条记录的导入,这些记录的插入时间比您每次循环读取一条记录的时间短。我甚至有一个2000万的记录文件只需要16分钟。
答案 4 :(得分:0)
老问题,但在寻找我自己的解决方案之后,我遇到了this code project article,这非常好。基本上使用Linq2Sql属性来构建DataTable,然后使用SQLBulkCopy进行插入,这比基本的Linq2Sql实现要快得多。文章中的代码可能会使用一些清理,并且可能会在使用外键的更复杂的场景中出现(我的模型中没有任何内容,尽管在数据库中有)但完全符合我的需求。