对SqlBulkCopy进行故障排除,不做最小的日志记录

时间:2013-10-28 12:06:42

标签: performance sql-server-2008-r2 sqlbulkcopy

根据提交的提示here,我创建了一个QueuedDataReader,其中ConcurrentQueue包含IDataReader,因此我可以将其传递给SqlBulkCopy并将数据“流”到数据库中。

它工作正常,并且速度非常快,但是日志文件的增长速度非常快,即使我相信我已经实现了所有建议的herehere(以及其他许多地方)。

两个可能重要的细节是:

  • 我正在并行插入十几个表(即每个表Task个)
  • 这些表有IDENTITY列(SqlBulkCopy没有插入),所以我不认为'SORT'条款是相关的。

除此之外:

  • 我开始插入时表格为空。
  • 我在PRIMARY KEY上尝试了CLUSTERED和NONCLUSTERED索引,没有太多可观察到的差异。
  • 我正在使用SqlBulkCopyOptions.TableLock
  • 我尝试过使用和不使用UseInternalTransactions以及各种BatchSizes。
  • 数据库处于SIMPLE恢复模式
  • 这些表确实有FK约束,但我已经尝试禁用/重新启用它们并且它不会阻止日志文件增长(插入期间)

问题:

  • 我可以通过哪些方法来尝试解决可能导致日志文件增长的问题?

1 个答案:

答案 0 :(得分:0)

在写我的问题时,我发现了另一个优秀的资源here,它指出BatchSize是一个潜在的罪魁祸首。

  

结果非常令人惊讶。如果我们使用BatchSize参数,   当我们将其设置为较低的值时,性能会变得越来越差。

     

使用非常小的值来为批量大小的网络带宽   在整个过程中保持低于20%的使用率(请注意   500批量图表的上限为25%,与之不同   其他图表)。低于10.000的任何值都会降低a的性能   非常沉重的方式,导致非常糟糕的时间和繁重的日志文件使用。

     

当我们达到批量大小10.000时,那么时间的差异   各种测试变得非常小。但是,因为我们有8个线程   每个写入750.000行,然后我们只发送了75个数据块   来自每个线程。不用说,获得了最佳性能   当我们使用0作为BatchSize时,将整个750.000行发送到一个   批次。

     

除此之外,发现是否有任何好处可能会很有趣   从性能,通过使用BatchSize参数。我们没找到   在线书籍中提到的任何东西也没有我们见过任何东西   在我们的经历中有趣,这引导我们说最好的   与BatchSize有关的事情是将它留给零,这就是它   默认值,因为任何不同的值都会减少   负载过程的性能。

由于超时错误,我之前放弃了BatchSize = 0,但是通过将我的BulkCopyTimeout设置为零,我得到了一些日志文件增长,但远远低于以前。

<强>更新即可。经过长时间的手动测试后,我终于开始编写自动化测试套件,尝试使用BatchSize(0-5000),入队率和聚簇/非聚簇索引的变体。 (就我而言,我正在将数据并行写入十几个表格。)

这是我发现的:

  • 测试200000个插页:如果主键为CLUSTERED BatchSize为零,则 no 日志文件增长。
  • 测试100万次插入:即使BatchSize = 0也会使日志文件增长(尽管比其他BatchSizes要小得多)。无论BatchSize如何,CLUSTERED仍会阻止日志增长。
  • 在这些条件之外,一切都取决于插入速度。一旦我'推'太硬,日志文件就会开始增长。

注意,我的测试以给定的速率将数据写入包含在IDataReader中的队列,该队列由BulkInsert队列化。每个表的一个队列/ BulkInsert。下一步是尝试使用更大的数据集。