通过C#优化这个大型SQL插入的策略?

时间:2013-09-18 15:33:58

标签: c# sql-server file insert sqlcommand

我需要在数据库中插入大约150万个文件。 每个记录都插入一个包含文件名的密钥。

捕获:当前未唯一标识文件。

所以,我们想要做的是,对于每个文件:

  • 插入记录。记录中的一个字段应包括一个亚马逊S3密钥,该密钥应包括新插入记录的ID。
  • 重命名文件以包含ID,使其与密钥的格式匹配。

我能想到的最好的事情是:

  • 运行单个insert命令,返回添加的行的ID。
  • 将其作为属性添加回我正在循环的单个业务对象。
  • 生成更新语句,更新S3密钥以包含ID
  • 输出文件,将ID连接到文件名的末尾。

据我所知,这看起来像是:

  • 150万个插入语句
    • 单个SqlCommand执行和读取,因为我们需要ID返回),
  • 在对象上设置属性的150万次。
  • 生成并执行了150万条更新语句
    • 也许可以把它作为一个巨大的连接更新语句来同时完成它们;不确定是否有帮助
  • 150万份文件副本。

我无法绕过实际的文件部分,但对于其他部分,是否有更好的策略我没有看到?

2 个答案:

答案 0 :(得分:3)

如果您使客户端应用程序生成ID,您可以使用直接SqlBulkCopy一次插入所有行。它将在几秒钟内完成。

如果要保留列的IDENTITY属性,可以运行DBCC CHECKIDENT(RESEED)将身份计数器提前1.5米,以便为您提供可插入的保证间隙。如果行数不是静态已知的,则可以在完成之前以100k的较小块执行插入。

答案 1 :(得分:1)

通过不依赖数据库为每行生成ID,您将把SQL语句的数量减少一半。在本地执行所有操作(包括分配ID),然后在最后使用identity_insert on执行一批插入。

这将导致SQL Server将您的ID用于此批记录。

如果这仍然太慢(并且可能有150万次插入),则下一步是将数据输出到文本文件(XML,逗号分隔或其他),然后对文件执行批量导入操作

我认为那是你能够做到的那么快。