使用SqlBulkCopy插入行

时间:2011-01-18 19:28:00

标签: sql-server linq-to-sql transactions sqlbulkcopy

我正在将部分Linq切换为Sql代码以使用SqlBulkCopy,问题是我需要在两个表中进行两次数千行的插入。

该服务将获取您的10,000个链接(从站点地图,反向链接构建器等导入),并将它们切换为每个Feed的X的RSS源以进行聚合。问题是,我已经有一张 3200万行的表格。如果我正在执行linq到sql插入,它取决于站点流量5到10分钟之间的任何地方加载10,000链接。

结构非常基础。

供稿:Id bigint(PK),标题varchar(1000),描述varchar(1000),发布日期时间,聚合日期时间null,ShortCode varchar(8)[过时,不再插入,但是用于遗留数据]

项目:Id bigint(PK),FeedId bigint(FK),标题varchar(1000),描述varchar(1000),发布日期时间,ShortCode varchar(8)[过时,不再插入,但用于遗留数据],ShortId bigint null [插入后更新为等于Id(用于分区)]

FutureItems :Id bigint(PK),FeedId bigint(FK),标题varchar(1000),描述varchar(1000),发布日期时间,ShortCode varchar(8)[陈旧,不再插入,但用于遗留数据],ShortId bigint null [插入后更新为等于Id(用于分区)]

OldItems :Id bigint(PK),FeedId bigint(FK),标题varchar(1000),描述varchar(1000),发布日期时间,ShortCode varchar(8)[陈旧,不再插入,但用于遗留数据],ShortId bigint null [插入后更新为等于Id(用于分区)]

因此,如果您的Feed大小为20,则会在Feeds表中获得500个插入,然后将10000个插入到Items表中,然后更新运行以将ShortId设置为Id。每晚一次,作业运行将数据分成另外两个表,并将未来的项目转移到Items表中。

我读到SqlBulkCopy可以完成2000万行,但是我找不到任何使用FK约束进入多个表的好例子。

我们的SQL服务器是一个“怪物”,特别是对于这个应用程序。它是SQL 2008 R2 Web,Windows 2008 R2 Enterprise,12GB Ram,双核4 Xeons @ 2.8ghz。

我们的网络服务器是没有数据库服务的克隆。

插入链接时CPU运行大约85%,数据库填充RAM。

如果SqlBulkCopy不好,任何建议都是受欢迎的,我们有付费的客户生气,我不是DBA,只是一个普通的程序员。

2 个答案:

答案 0 :(得分:1)

SqlBulkCopy确实比普通插入更快。但速度更快,因为它可以将每秒运行1000次插入的作业转换为10000次/秒的作业。如果您在10分钟内只能完成10000个链接,那么您必须遇到不同的问题,批量复制不太可能解决。

您需要先调查为什么插入10000个链接所需的时间非常长。只有在您了解之后才能进行调用以确定是否转移到SqlBulkCopy是一种解决方案。我知道您不是DBA,但是我将向您发送一份“dbaish”白皮书,用于解决SQL Server性能问题:Waits and Queues。这不是一个cookie切割器配方解决方案,实际上是一种方法,将教你如何识别SQL Server中的性能瓶颈。

并解决您的问题:如果有约束,如何使用SqlBulkCopy?更通用的问题是当约束到位时如何进行批量插入操作?对于严重的卷,实际上会禁用约束,执行批量上载,然后启用约束。为了更加简化的在线操作,停机时间最短(数据库在禁用约束时基本上处于“关闭状态”),使用不同的策略,即在临时表中预加载数据,对其进行验证,然后使用分区切换操作,请参阅Transferring Data Efficiently by Using Partition Switching

答案 1 :(得分:0)

我认为仅使用普通批量插入的真正问题是您需要来自其他表的初始插入的feed ID。这就是我要做的。使用批量插入插入登台表。然后使用存储过程以基于集合的方式对真实表进行插入。您可以使用初始插入中的输出子句到feed表,以获取表变量,其中包含插入其他表所需的feed ID。