【问题标题】:Fastest and best method for importing file contents into a database将文件内容导入数据库的最快和最佳方法
【发布时间】:2011-04-03 20:46:41
【问题描述】:

我有一些文件夹,每天大约有 3000 个新的 csv 文件进入,每个文件包含 50 到 2000 行信息。

目前,有一个流程可以一次提取一个文件,一次提取每一行,然后将其发送到存储过程以将内容插入数据库。

这意味着在一天的过程中,在下一个 3000 个文件进入之前,它可能很难通过 3000 个文件!

我正在寻求改进这个过程并有以下想法

  • 使用 C# 4.0 的新并行功能允许一次处理多个文件,仍然逐行传递到存储的过程
  • 创建一个新的临时数据库表,文件中的所有行可以一次插入其中,然后对临时表中新添加的行调用存储过程。
  • 将进程拆分为 2 个任务。一项工作是将文件中的数据读取到临时数据库表中,另一项工作是处理临时表中的行。

关于我如何看待这样做的任何其他想法?目前每个文件最多可能需要 20 秒,我真的很想大大提高这方面的性能。

【问题讨论】:

  • 使用存储过程进行插入真的很重要吗?
  • 3000 个文件 x 1000 行平均 = 您向数据库引擎发送 3M 查询,一次一个,并执行 3M 存储过程(通常被解释),一次一个,你问为什么它很慢?跳过所有开销、锁定数据库、删除索引和批量加载。然后重新启用。 TPL 在这里帮不了你,因为瓶颈是数据库引擎。
  • 您正在加载数据仓库吗?

标签: c# sql performance import file-processing


【解决方案1】:

SQL Server 批量插入可能正是您所需要的

http://msdn.microsoft.com/en-us/library/ms188365.aspx

您可能会看到所有这些插入需要很长时间的另一个问题是,每次添加一行时,您的表可能会被重新索引。像这样的搜索将提供很多关于如何从当前程序中获得更好性能的好文章 http://www.google.com/search?q=sql+insert+performance

【讨论】:

    【解决方案2】:

    您可以使用 SQL Server 本地 BCP 实用程序。

    有关 BCP 实用程序的更多信息可以在这里找到:Importing and Exporting Bulk Data by Using the bcp Utility

    你也可以看看:About Bulk Import and Bulk Export Operations

    【讨论】:

    • 谢谢,我以前用过 bcp,它看起来对我需要做的事情很有用。使用 bcp,您是否知道是否也可以为每一行添加文件名?例如如果它正在处理 file2.csv,它将将该文件中的所有行连同值“file2.csv”一起导入数据库中的一列。我猜这可能是不可能的,你只能插入文件中的内容。
    • @Graeme:我认为这是不可能的。如果您知道您的两个文件架构,那么您可以创建 TEMPORARY 表,使用 bcp 快速导入这两个文件,然后运行将数据从临时表移动到真实表的存储过程。将数据导入 SQL Server 后,数据移动速度会很快。
    【解决方案3】:

    假设要导入的所有 3000 个文件每个都有 2000 行。那是每天 600 万行。瓶颈可能不在执行插入的客户端,而在于数据库本身。如果在相关表上启用了索引,则插入可能会很慢,具体取决于表的索引程度。哪些迹象使您得出这样的结论:是数据库在等待执行某项操作,而滞后的是导入例程,而不是相反?

    【讨论】:

    • 取决于该存储过程正在做什么,它可能远远超过 600 万行。我正在想象一个存储过程,它将每行输入切成小块,以便插入到多个表中。可能是 2、3 或 37 个表参与类似的事情。
    • 我的意思是,在解决问题之前,您必须找出问题所在。如果您在 SP 中进行繁重的字符串操作,您应该检查服务器 CPU。您可能希望在客户端而不是服务器上进行字符串操作。如果服务器 CPU 被挂钩,多线程客户端只会加剧问题。如果您的目标表被大量索引,您可能希望禁用索引并在导入后重新启用。你是什​​么意思“想象”?目前这只是一个假设问题吗?
    • 我不反对你。我只是说,您估计每天 600 万行输入可能需要每天 1200 万、1800 万或 2.22 亿次数据库插入。发现或多或少从电子表格中取出一行并将其分解以插入多个 SQL 表的过程并不罕见。至于想象,我在想象 OP 的存储过程可能会通过处理所有这些数据来做什么,似乎每行一个事务。
    【解决方案4】:

    你说

    目前,有一个流程到位 它会一次提取这些文件 时间并每次一行一行 并将其发送到存储过程 将内容插入数据库。

    (已添加重点。)

    这似乎意味着一行等于一笔交易

    解决这个问题。

    • 对文件进行预处理,以便它们 可接受批量装载。
    • 预处理文件,使它们形成 有效的 SQL INSERT 语句,并加载 他们那样。 (在单笔交易中。)

    我猜这两个听起来都像是“替换你的存储过程”。但真正的重点是减少交易数量。这些选项中的任何一个都会将此流程的交易数量从每天 600 万次(最坏情况)减少到每天 3000 次。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-07-25
      • 1970-01-01
      • 2011-02-23
      • 1970-01-01
      • 2010-10-04
      • 2020-07-28
      • 1970-01-01
      • 2014-01-11
      相关资源
      最近更新 更多