0

我正在使用 Dapper 将来自实时馈送的数据插入 Sql Server,所以我关心性能。最近,我注意到一些奇怪的事情。
开箱即用,如果你给 Dapper 一个集合和一个插入查询,它会为每个元素触发插入语句。我的测试表明我可以通过这种方式在 1 秒内插入大约 1800 个具有 12 个字段的对象(仅计算connection.Execute(...)运行时间。
现在,我没有在 Dapper 中找到批量插入功能并实现了我自己的(构造参数列表和 sql 查询)。之后那,我发现我只能在大约 3 秒内插入一批(限制为 1000 行)(同样,只计算connection.Execute(...)调用。
所以,这使我的批处理慢了近 6 倍而不是在单独的查询中发送每一行。有人可以向我解释吗?我认为人们使用批处理操作来加速这个过程。
我希望插入时间最多为 1 秒。我使用本地网络上的 Sql Server 2012 Standard。我要插入的表仅在主键(即 bigint 字段)上有聚集索引,没有非聚集索引和触发器。
我可以发布代码,但真的没有什么特别的

4

2 回答 2

2

如果您想要获得最佳性能,我不确定您为什么要使用 Dapper Execute 扩展方法。

以最佳性能插入的最佳免费方式是SqlBulkCopy直接使用该类。

免责声明:我是Dapper Plus项目的所有者

该项目为以下操作提供了简单的支持:

  • 批量插入
  • 批量更新
  • 批量删除
  • 批量合并

例子:

// CONFIGURE & MAP entity
DapperPlusManager.Entity<Order>()
                 .Table("Orders")
                 .Identity(x => x.ID);

// CHAIN & SAVE entity
connection.BulkInsert(orders)
          .AlsoInsert(order => order.Items);
          .Include(x => x.ThenMerge(order => order.Invoice)
                         .AlsoMerge(invoice => invoice.Items))
          .AlsoMerge(x => x.ShippingAddress);   
于 2017-01-16T15:52:47.440 回答
0

理想的批处理大小可能因服务器而异,关键因素是日志记录,这将影响插入的资源密集程度以及在您看到性能下降之前您可以制作多大的批处理。

快速插入/更新的关键是确保您满足最小日志记录的要求,请查看此Microsoft 白皮书。不要惊慌——您不需要阅读所有内容——查看描述满足“最少日志记录”条件的表格(您需要与您的 DBA 交谈)。

一旦你的日志记录尽可能少,那么你需要查看你的 SPOOLS 执行计划,如果一个批处理开始假脱机到 Tempdb,那么你会遇到一个戏剧性的减速。关键是保持批次足够小以保留在缓冲区 (RAM) 中。但是可用的缓冲区空间量将取决于其他进程。

注意:TABLOCK 与 TABLOCKX 不同。

于 2017-01-17T18:44:12.153 回答