C#将大量数据从CSV导入数据库

时间:2010-04-14 22:31:53

标签: c# multithreading csv etl relational-database

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

  • 需要格式化数据(例如,名称列需要分为名字和姓氏等)。
  • 我需要尽可能有效地做到这一点,即时间限制

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

7 个答案:

答案 0 :(得分:4)

您将受到I / O限制,因此多线程不一定能让它运行得更快。

上次我这样做时,它是十几行C#。在一个线程中,它运行硬盘的速度与从盘片读取数据的速度一样快。我从源文件中一次读取一行。

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

答案 1 :(得分:3)

您可以使用csvreader快速阅读CSV。

假设您正在使用SQL Server,则使用csvreader的CachedCsvReader将数据读入DataTable,您可以将其与SqlBulkCopy一起加载到SQL Server中。

答案 2 :(得分:2)

我同意你的解决方案。一次读取一行文件应该避免一次将整个文件读入内存的开销,这应该使应用程序快速有效地运行,主要是花时间从文件中读取(相对较快)并解析行。我要注意的一点是要注意你是否在CSV中嵌入了换行符。我不知道您使用的特定CSV格式是否实际上会在数据中的引号之间输出换行符,但这当然会混淆此算法。

另外,我建议在将insert语句(包括许多insert语句包含在一个字符串中)之前将它们发送到数据库,如果这不会在检索生成的键值时出现问题,这些键值需要用于后续的外键(希望如此)您不需要检索任何生成的键值)。请记住,SQL Server(如果这是您正在使用的)只能处理每批2200个参数,因此请将批量大小限制为此。我建议使用参数化TSQL语句来执行插入。我怀疑插入记录所花费的时间比从文件中读取记录要多。

答案 3 :(得分:1)

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

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

答案 4 :(得分:0)

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

答案 5 :(得分:0)

逐行读取CSV文件的内容到内存DataTable中。您可以在填充DataTable时操纵数据(即:拆分名字和姓氏)等。

将CSV数据加载到内存中后,使用SqlBulkCopy将数据发送到数据库。

有关文档,请参阅http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlbulkcopy.writetoserver.aspx

答案 6 :(得分:0)

如果您真的想在C#中创建它,请创建&填充DataTable,截断目标db表,然后使用System.Data.SqlClient.SqlBulkCopy.WriteToServer(DataTable dt)。