Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# SqlBulkCopy性能_C#_Sql Server_Sqlbulkcopy - Fatal编程技术网

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文章:

如果目标是B-树(即聚集索引表),很遗憾,performant bulk insert最重要的原则之一,即排序输入行集,无法声明。如此简单,ADO.NETSQLClient没有(OleDb)的等价物。由于引擎不知道数据已经排序,它将在计划中添加一个排序操作符,该操作符没有那么糟糕,除非它溢出。为避免溢出,使用小批量(~10k)。请看我的原始观点:所有这些都只是,而不是通过OleDB 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线程将其分发给多个盒子。