使用c#将大量或行写入mssql数据库

时间:2013-03-05 12:58:45

标签: c# .net tsql stored-procedures

我遇到的问题是使用c#应用程序将大量数据行提交到数据库(sql 2008 R2)。

我现在正在做的是,我正在创建一个相当大的XML文件(大约30Mb),该文件将包含应该插入到数据库中的大约40.000行。

从这个xml文档我作为变量传递给数据库我有一个存储过程,它将从中读取数据并进行适当的插入或更新。

伪c#代码:

String xml = xmlWriter.ToString();
SqlCommand cmd = new SqlCommand("sp_CommitData", connection)
cmd.Variables.AddWithValue("@xml", xml);
SqlDataReader reader = cmd.ExecuteReader();
while(reader.Read())
{ 
 /* Read return data */
}

伪tsql代码:

INSERT INTO DataTable
xmldata.value('@uID','[uniqueidentifier]') AS [uID]
FROM<
@xml.nodes('/data/m/r') [xmldata](xmldata)  

这种方法在过去对我来说效果很好,但现在数据似乎对于工作方法来说是巨大的......只需要提交数据就需要3分钟以上,而这只是很长时间。 :(

这一定是一个很常见的问题,你们在类似的场景中做得怎么样? 对于如何使用c#提交大量数据,你有什么好的指示吗?解决方案必须是线程安全的,所以我不太喜欢bcp或类似的方法。

亲切的问候 德鲁

2 个答案:

答案 0 :(得分:5)

最快的方法是使用SqlBulkCopy,它将使用SQL的批量加载功能。

XML方法的问题在于,您首先必须从您的行集/ IEnumerable(您必须从什么开始?)转换为XML,然后通过网络推送它。 XML是一种非常臃肿的格式,当你提到很多行时,这就很重要。

批量复制方法可让您逐行流式传输,而无需实现整个内容(进入内存或磁盘),从而减少内存占用。

如果数据量非常大,您可能希望首先将它加载到临时表中(因此没有实际表的事务)和插入(或Merge)真实的事物。

你对线程安全的意思是什么?如果您希望此操作不阻止客户端,您可以轻松地在后台线程上启动它。没有外部流程或任何您需要开始执行此操作,它在进程中运行。

答案 1 :(得分:0)

感谢您输入此问题。我已经开始查看SqlBulkCopy,但一段时间后停止了,因为我需要一个存储过程,它将在逻辑附近执行数据。
鉴于我可能有很多并发线程来保存数据的服务,我无法用数据填充临时表,以后再从中读取内容。

然后我把注意力转向表值参数,并在那里找到了答案。我有点惊讶的是,我之前没有尝试过,因为它运作得非常好。在性能数据中,保存从大约45秒到不到5秒!

感谢您指点我的方向。