11

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

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

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

4

7 回答 7

5

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

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

如果您不热衷于自己编写,可以尝试FileHelpers库。您可能还想看看Sébastien Lorion 的作品。他的 CSV 阅读器是专门为处理性能问题而编写的。

于 2010-04-14T22:35:28.827 回答
3

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

假设您使用的是 SQL Server,则使用 csvreaderCachedCsvReader将数据读取到 DataTable 中,您可以使用SqlBulkCopy将其加载到 SQL Server 中。

于 2010-04-14T22:49:08.240 回答
2

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

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

于 2010-04-14T22:37:21.707 回答
1

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

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

于 2010-04-14T22:41:05.203 回答
0

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

于 2010-04-14T22:51:00.490 回答
0

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

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

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

于 2010-04-14T22:58:53.350 回答
0

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

于 2010-04-14T23:04:06.707 回答