我们有一个C#应用程序,用于解析文本文件中的数据。然后,我们必须根据文本文件中的信息更新sql数据库中的记录。将数据从应用程序传递到SQL服务器的最有效方法是什么?
我们当前使用分隔字符串,然后遍历存储过程中的字符串以更新记录。我也在使用TVP(表值参数)进行测试。还有其他选择吗?
我们的文件包含数千条记录,我们希望解决方案花费最少的时间。
答案 0 :(得分:2)
请不要使用DataTable
因为只是浪费CPU和内存而没有任何好处(除了可能熟悉之外)。在回答以下问题时,我已经详细介绍了一种非常快速和灵活的方法,这与以下问题非常类似:
How can I insert 10 million records in the shortest time possible?
该答案中显示的示例仅适用于INSERT,但可以轻松调整以包含UPDATE。此外,它一次性上传所有行,但也可轻松调整为X数量的记录设置计数器,并在传入许多记录后退出IEnumerable方法,并且一旦没有更多记录,则关闭文件。这将需要将文件指针(即流)存储在静态变量中以继续传递给IEnumerable方法,以便它可以在下一次的最近位置被提前并拾取。我有一个这个方法的工作示例,如下面的答案所示,虽然它使用SqlDataReader
作为输入,但技术是相同的,只需要很少的修改:
How to split one big table that has 100 million data to multiple tables?
从某种角度来看,50k的记录甚至还不接近"巨大的"。我一直在使用我在这里显示的400万行文件的方法上传/合并/同步数据,并且打了几千万行(或更多行)。
不的事情:
DataTable
:正如我所说,如果您只是为了与TVP一起使用它,那就是浪费CPU,内存和时间。有效的东西,但不像正确完成的TVP那样灵活(即传递返回IEnumerable<SqlDataRecord>
的方法)。这些都没问题,但为什么要将记录转储到临时表中,只是为了在内联时将它们解析到目的地?
SqlBulkCopy
答案 1 :(得分:0)
在我看来,最好的方法是创建一个临时表,然后使用SqlBulkCopy插入到临时表(https://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlbulkcopy%28v=vs.110%29.aspx),然后只需根据临时表更新表。
根据我的测试(使用Dapper和LINQ),作为批量或批量更新比仅创建临时表并向服务器发送命令以基于临时表更新数据花费的时间更长。这个过程更快,因为SqlBulkCopy以快速方式本地填充数据,其余部分在SQL服务器端完成,经过较少的计算步骤,此时的数据驻留在服务器端。