1

我在使用 ac# 应用程序将大量数据行提交到数据库(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 或类似方法。

亲切的问候德鲁

4

2 回答 2

5

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

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

批量复制方法将让您逐行流式传输它,而不必将整个事物具体化(进入内存或磁盘),从而减少内存占用。

如果数据量很大,您可能希望先将其加载到临时表中(因此没有真实表的事务),然后将其插入(或合并)到真实表中。

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

于 2013-03-05T13:05:09.283 回答
0

感谢您对此问题的意见。我已经开始查看 SqlBulkCopy 但过了一会儿就停止了,因为我需要一个存储过程来处理逻辑附近的数据。
鉴于我可能有许多并发线程到保存数据的服务,我无法用数据填充临时表,然后再从中读取内容。

然后我将注意力转向表值参数并在那里找到了我的答案。我有点惊讶我之前没有尝试过这个,因为它效果很好。在性能数据中,保存时间从大约 45 秒缩短到不到 5 秒!

感谢您为我指明了这个方向。

于 2013-03-06T13:01:33.340 回答