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

本文关键字:数据 mssql 数据库 使用 | 更新日期: 2023-09-27 18:02:25

我使用c#应用程序提交大量数据行到数据库(sql 2008 R2)的代码出现问题。

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

从我作为变量传递给数据库的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或类似的方法。

亲切的问候了

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

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

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

大容量复制方法将允许您逐行流式传输,而不必将整个内容具体化(到内存或磁盘上),从而降低内存占用。

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

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

感谢您对这个问题的意见。我已经开始看SqlBulkCopy,但停了一会儿,因为我需要有一个存储过程,将做数据接近逻辑。
考虑到我可能有许多并发线程到保存数据的服务,我不能用数据填充临时表,然后从中读取内容。

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

谢谢你给我指出这个方向。