SqlBulkCopy性能

Mic*_*l S 7 c# sql-server sqlbulkcopy

我正在努力提高批量负载的性能; 100多万条记录+每日.

我把它移到了使用IDatareader接口来代替数据表,并且确实获得了显着的性能提升(每分钟500,000条记录).目前的设置是:

  • 用于解析分隔文件的自定义缓存读取器.
  • 将流读取器包装在缓冲流中.
  • 一个自定义对象读取器类,它枚举对象并实现IDatareader接口.
  • 然后SqlBulkCopy写入服务器

大部分性能瓶颈直接进入SqlBulkCopy.WriteToServer.如果我对过程进行单元测试,但只排除WriteToServer过程大约1分钟后返回.WriteToServer正在增加15分钟+.对于单元测试,它位于我的本地计算机上,因此数据库存在相同的驱动器,因此不必通过网络复制数据.

我正在使用堆表(没有索引;聚集或非聚集;我已经玩过各种批量大小而没有性能上的重大差异).

有必要减少加载时间,所以我希望有人可能现在可以从这个开局中挤出更多的血液.

Rem*_*anu 1

为什么不直接使用SSIS呢?

无论如何,如果您从解析到 IDataReader 进行了处理,那么您已经走在正确的道路上了。要优化 SqlBulkCopy 本身,您需要将注意力转向 SQL Server。关键是最少记录的操作。您必须阅读这些 MSDN 文章:

如果您的目标是 B 树(即聚集索引表),则不幸的是,无法声明高性能批量插入的最重要原则之一,即排序输入行集。就这么简单,ADO.Net SqlClient 没有SSPROP_FASTLOADOPTIONS -> ORDER(Column)(OleDb) 的等效项。由于引擎不知道数据已经排序,因此它会在计划中添加一个排序运算符,这并没有那么糟糕,除非它溢出。为避免溢出,请使用小批量 (~10k)。看我原来的观点:所有这些都只是SSIS中的选项和点击设置,而不是深入研究 OleDB MSDN 规范...

如果您的数据流一开始就未排序或者目标是堆,那么我上面的观点是无声的。

然而,实现最少的日志记录仍然是获得良好性能的必要条件。