优化大量插入性能......?

时间:2011-01-10 20:10:23

标签: performance sql-server-2008-r2

鉴于:SQL Server 2008 R2。退出数据光盘中的一些速度。记录光盘滞后。

必需:很多插入物。像10.000到30.000行一样,每秒有两个索引的简单表。插入物具有内在的顺序,不会重复,因为插入顺序不能短期保持(即多个平行插入是可以的)。

到目前为止:将数据累积到队列中。定期(异步线程池)将最多1024个条目清空到排队的工作项中。 Threadpool(自定义类)有32个可能的线程。打开32个连接。

问题:性能下降了300倍......每秒只插入大约100到150行。日志等待时间高达40% - sql server中处理时间(每秒ms)的45%。服务器CPU负载很低(4%到5%左右)。

不可用:批量插入。数据必须尽可能实时写入光盘。这几乎是通过系统运行的数据的归档过程,但是有些查询需要定期访问数据。我可以尝试将它们转储到光盘上,并且每秒使用批量上传1-2次....将试一试。

任何人都有一个聪明的想法?我的下一步是将日志移动到快速光盘集(128gb现代ssd)并查看当时会发生什么。显着的性能提升可能会带来很大的不同。但即便如此......问题在于是否/什么是可行的。

所以,请开启聪明的想法。

3 个答案:

答案 0 :(得分:4)

好的,不管我自己。试试SqlBulkCopy,批量处理多达65536个条目,并以异步方式每秒刷新一次。将报告收益。

答案 1 :(得分:3)

我在这里遇到完全相同的问题,所以我将完成我正在采取的改善我的表现的步骤。

  • 将日志和dbf文件分隔到不同的主轴集
  • 使用基本恢复
  • 除了插入顺序不重要这一事实外,您没有提及任何索引要求 - 在这种情况下,不应使用除标识列以外的任何内容的聚簇索引。
  • 从1开始再次扩展并发性,并在性能变平时停止;任何事情都可能会影响表现。
  • 而不是将磁盘降级到bcp,并且在使用SQL Server 2008时,请考虑一次插入多行;此语句在单个sql调用中插入三行

    INSERT INTO表值(1,2,3),(4,5,6),(7,8,9)

我每秒从单个线程中获得大约500个不同的插入。在排除网络和CPU(客户端和服务器上都为0)之后,我认为服务器上的磁盘io应该受到责备,但是三次批量插入每秒会产生1500次插入,这排除了磁盘io。

很明显,MS客户端库有一个上限(并且潜入反射器显示了一些毛茸茸的异步完成代码)。

以这种方式批处理,在调用insert之前等待接收x事件,我现在从单个线程插入每秒约2700次插入,这似乎是我的配置的上限。

注意:如果您没有始终到达的常量事件流,您可以考虑添加一个计时器,在一段时间后刷新您的插入(以便您看到当天的最后一个事件!)

答案 2 :(得分:1)

提高插入性能的一些建议:

  • 增加ADO.NET BatchSize
  • 明智地选择目标表的聚簇索引,以便插入不会导致聚簇索引节点拆分(例如autoinc列)
  • 首先插入临时堆表,然后发出一个大的“insert-by-select”语句将所有临时表数据推送到实际目标表中
  • 应用SqlBulkCopy
  • 选择“完整”恢复模式的“批量记录”恢复模型实例
  • 在插入之前放置一个表锁(如果您的业务场景允许)

取自Tips For Lightning-Fast Insert Performance On SqlServer