2010-04-14 132 views
10

将大量数据从CSV(300万行+)加载到数据库的最有效方法是什么?C#将大量数据从CSV导入到数据库

  • 的数据需要被格式化(例如名称列需要被分成第一名和姓等)
  • 我需要做这在高效地即时间限制

我正在阅读,使用C#应用程序逐行读取,转换和加载数据?这是理想的,如果不是,我的选择是什么?我应该使用多线程吗?

+0

时间限制有多严格? – Jake 2010-04-14 22:54:11

回答

4

您将被I/O绑定,因此多线程不一定会使其运行速度更快。

上次我做到了这一点,它大概有十几行C#。在一个线程中,它以尽可能快的速度运行硬盘,因为它可以从盘片中读取数据。我一次从源文件中读取一行。

如果你不喜欢自己写,你可以试试FileHelpers库。您可能还想看看Sébastien Lorion's work。他的CSV阅读器专门用于处理性能问题。

+0

是的,c#io库的缓冲区很好。最近我不得不在一分钟内从一个csv转换到另一个(1.5米线)。 – 2010-04-14 22:46:03

+1

我也推荐FileHelpers。它使我不必编写解析器来处理其中包含逗号的值。如果CSV有任何这样令人讨厌的细节,请考虑FileHelpers。 – 2010-04-14 22:49:18

+0

我知道在过去,驱动器上的寻找时间是一个问题。在大图像文件的情况下,我们将从一个驱动器读取数据并写入另一个驱动器,以减少重新定位驱动器磁头的次数。 – yamspog 2010-04-14 23:03:02

2

我同意你的解决方案。一次读取一行文件应避免一次将整个文件读入内存的开销,这应该使应用程序快速高效地运行,主要是花时间从文件中读取(这相对较快)并解析行。我注意的一点是要注意你的CSV中是否嵌入了换行符。我不知道您使用的具体CSV格式是否可能实际上在数据中的引号之间输出换行符,但当然可能会混淆该算法。我想建议在将它们发送到数据库之前将插入语句(在一个字符串中包括许多插入语句)批量化,如果这在检索您需要用于后续外键的生成的键值时不存在问题(希望你不需要检索任何生成的键值)。请记住,SQL Server(如果这就是你所使用的)每批只能处理2200个参数,所以限制你的批量大小来解决这个问题。我建议使用参数化的TSQL语句来执行插入操作。我怀疑插入记录需要花费更多的时间,而不是从文件中读取它们。

1

你没有说明你正在使用哪个数据库,但考虑到你提到的语言是C#我将假设SQL Server。

如果无法使用BCP导入数据(如果需要大量处理,听起来好像不行),那么SSIS很可能是下一个最快的选项。它不是世界上最好的开发平台,但速度非常快。肯定比任何可以在任何合理时间内自行编写的应用程序都快。

+0

我与Greg和JayRiggs合作。跳过C#(除非您正在为SQL Server编写CLR模块)。让SQL完成这项工作。如果您没有听说过,那么从文件中处理大量数据是非常好的。 ;)这会为您节省打开conxns等各种令人头疼的问题。 – jcolebrand 2010-04-14 22:52:38

+0

这使得单元测试非常困难? – guazz 2010-04-14 23:26:13

+0

这实际上并不是单元测试非常有用的问题。人们过多地关注单元测试,忽视更大的图景。你应该测试的是,如果已知CSV数据集,那么进入数据库的数据是正确的,并且按预期处理已知坏的情况(固定的,丢弃的或失败的)。如果你这样做,那么它如何进入数据库并不重要。所以从任何实际角度来看,我都会说SSIS和其他任何东西一样可测试。 – 2010-04-15 11:26:20

3

您可以使用csvreader来快速读取CSV。

假设您正在使用SQL Server,您可以使用csvreader的CachedCsvReader将数据读取到DataTable中,您可以使用该数据表将SqlBulkCopy加载到SQL Server中。

+0

这就是我使用的。我喜欢csvreader,它是访问分隔文件的一种非常方便的方式。 – galford13x 2010-04-14 23:12:25

+0

+1为SqlBulkCopy – Kiril 2010-04-14 23:41:35

0

BCP非常快,所以我会用它来加载数据。对于字符串操作,一旦数据在那里,我会在SQL上使用CLR函数。除了增加复杂性并损害性能之外,多线程无助于这种情况。

0

如果你真的想在C#中做到这一点,创建&填充一个DataTable,截断目标数据库表,然后使用System.Data.SqlClient.SqlBulkCopy.WriteToServer(DataTable dt)。

+0

不幸的是,我需要更新现有的记录,数据将每天加载。 – guazz 2010-04-14 23:27:17