C# SqlBulkCopy性能
我正在努力提高散装货物的性能;每天有上亿条记录 我将此移到使用C# SqlBulkCopy性能,c#,sql-server,sqlbulkcopy,C#,Sql Server,Sqlbulkcopy,我正在努力提高散装货物的性能;每天有上亿条记录 我将此移到使用IDatareader接口来代替数据表,并确实获得了显著的性能提升(每分钟多记录50万条)。当前设置为: 用于分析分隔文件的自定义缓存读取器 在缓冲流中包装流读取器 一个自定义对象读取器类,枚举对象并实现IDatareader接口 然后SqlBulkCopy写入服务器 性能瓶颈主要直接出现在SqlBulkCopy.WriteToServer中。如果我对进程进行单元测试,直到但不包括WriteToServer,该进程将在大约1分钟内
IDatareader
接口来代替数据表,并确实获得了显著的性能提升(每分钟多记录50万条)。当前设置为:
- 用于分析分隔文件的自定义缓存读取器李>
- 在缓冲流中包装流读取器李>
- 一个自定义对象读取器类,枚举对象并实现
接口李>IDatareader
- 然后
写入服务器SqlBulkCopy
SqlBulkCopy.WriteToServer
中。如果我对进程进行单元测试,直到但不包括WriteToServer
,该进程将在大约1分钟内返回WriteToServer
需要额外15分钟。对于单元测试,它在我的本地机器上,因此数据库所在的驱动器相同,因此不必通过网络复制数据
我使用的是一个堆表(没有索引;聚集或未聚集;我使用了不同的批处理大小,在性能上没有重大差异)
有必要减少加载时间,所以我希望现在有人能想出一个办法,从这个循环中挤出更多的血液 为什么不直接使用SSI 无论如何,如果您从解析到IDataReader进行了一次叛逆,那么您已经走上了正确的道路。要优化SqlBulkCopy本身,您需要将重点转向SQL Server。关键是最低限度地记录操作。您必须阅读以下MSDN文章:
然而,要获得良好的性能,实现最低限度的日志记录仍然是必须的。您正在运行发布模式吗?咬什么?你介绍过吗?在15分钟以上的时间里,CPU负载主要是在服务器上还是在客户机上?您实际复制了多少数据?大容量复制使用了哪些设置?复制期间的I/O负载是多少?是的,这是在释放模式下。32在我的本地进行单元测试。客户机与数据库运行在同一个设备上。保持稳定,进程的CPU使用率约为12%,内存为80k。对于这个单元测试,有1200万条记录。我使用了桌锁设置。好主意,我将在这个进程上运行sql事件探查器,看看它是否有什么结果;您应该看看客户端的CPU探查器,它可能比这里的sql探查器告诉您更多——听起来sql方面非常简单(这很好)。12%的CPU负载-可能是8核机器的1核最大负载-是吗?一条记录有多少字节?哦,最后,您是否在没有附加调试程序的情况下运行(甚至在发布模式下也可能)?为了帮助基准测试,您可能希望在预写服务器基准测试中包含自定义数据读取器。由于数据读取器是基于拉(pull-based,即lazy)的,因此排除WriteToServer可能也排除了可能的性能。自定义数据读取器中的瓶颈。我同意DB是重点;特别是考虑到所有的东西都是批量复制的苍蝇;1200万条记录在57秒内完成。在我本地的单元测试中,我使用简单的日志记录,但它是express edition。我将通过创建一个新的数据库并使用简单的日志记录,在我们的一个开发设备(企业版)上对此进行测试。但你需要所有其他因素。此外,对于快速版,我假设您的IO子系统不是普通的消费级(例如,一个大的5400RPM单驱动器)。如果IO是您的瓶颈,那么您需要在高速驱动器上进行测试。我在一台有更多资源的服务器上运行了此测试,并创建了一个简单的恢复数据库。这使它从每秒260万次又刷新了60万次记录。比这一切开始的地方多了110万。我还刚刚使用多线程对sql大容量复制进行了一些测试,其中有一些非常有希望的数字。4条线程跃升到每分钟600万条;而8人跳到了每分钟1200万人。非常有希望,但由于CPU利用率的原因,可能需要使用8线程将其分发给多个盒子。