SqlBulkCopy 性能

问题描述 投票:0回答:2

我正在努力提高散装负载的性能;数百百万条记录+每日。

我将其移至使用

IDatareader
界面代替数据表,并且确实获得了显着的性能提升(每分钟多了 500,000 条记录)。当前设置是:

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

大部分性能瓶颈直接位于

SqlBulkCopy.WriteToServer
。如果我对流程进行单元测试,直到但不包括
WriteToServer
,流程将在大约 1 分钟内返回。
WriteToServer
还需要 15 分钟以上。对于单元测试,它位于我的本地计算机上,因此数据库位于同一驱动器上,因此不必通过网络复制数据。

我正在使用堆表(无索引;集群或非集群;我尝试过各种批量大小,性能没有重大差异)。

有必要减少加载时间,所以我希望有人现在可以找到一种方法,从这次出现中挤出更多的血液。

c# sql-server sqlbulkcopy
2个回答
1
投票

为什么不直接使用SSIS?

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

如果您的目标是 B 树(即聚集索引表),则不幸的是,无法声明高性能批量插入的最重要原则之一,即排序输入行集。就这么简单,ADO.Net SqlClient 没有相当于

SSPROP_FASTLOADOPTIONS -> ORDER(Column)
(OleDb) 的功能。由于引擎不知道数据已经排序,因此它会在计划中添加一个排序运算符,这并没有那么糟糕,除非它溢出。为避免溢出,请使用小批量 (~10k)。请参阅我的原始观点:所有这些都只是 在 SSIS 中设置的选项和单击,而不是深入研究 OleDB MSDN 规范...

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

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


0
投票

我遇到了 SqlBulkCopy 超时问题。使用 VarChar/NVarChar 时,性能会显着降低。我将数据类型更改为文本,它立即得到处理。具体来说,我有一个包含两个字段的记录,即 VarChar(999)。我将这些字段的数据类型更改为文本,并插入了包含这两个字段的记录,每个字段包含 100,000 个字符。我不确定为什么文本数据类型有助于提高性能?我怀疑这与 SQL Server 在内存中存储文本的方式有关。

© www.soinside.com 2019 - 2024. All rights reserved.