SQL Server 是否支持来自多个连接的并行批量插入?

dir*_*101 2 sql-server-2008 sql-server concurrency bulk-insert sql-server-2017

SQL Server 是否支持对同一数据库表的并行批量插入?

对我的特定用例的一些说明:

  • 该表有一个由两个不同索引键组成的聚集索引和两个非聚集索引,每个索引由一个索引键组成。
  • 并行在这里意味着来自多个不同的连接。每个连接都是一个唯一的sqlalchemy.orm.session对象,每个Session使用该Session.bulk_insert_mappings()方法同时插入20k条数据。

我的具体问题:

  • 我试图了解 SQL Server 端的幕后情况。是否有所有批量插入的队列,并且每个批量插入都按照进来的顺序一个一个地执行?还是所有的插入都是同时进行的,并行的?
  • 我们还假设没有两个不同的连接会尝试插入相同的记录(基于主键),但是如果两个并行连接尝试插入会导致 PK 违规的记录怎么办?
  • 如果我们要求 SQL Server 2008 与 2017,上述问题的答案是否不同?
  • Microsoft 是否有关于此的任何类型的文档?

Pau*_*ite 6

Microsoft 是否有关于此的任何类型的文档?

是的,很多。一个特别好的参考资料是数据加载性能指南

我试图了解 SQL Server 端的幕后情况。是否有所有批量插入的队列,并且每个批量插入都按照进来的顺序一个一个地执行?还是所有的插入都是同时进行的,并行的?

批量插入没有什么特别的。没有特殊的队列,或类似的东西。每个都作为一个正常的命令进行处理,该命令将根据并发锁定活动继续或被阻止。需要明确的是:是并发的批量导入到同一个集群表来自不同服务器的连接是可能的

我们还假设没有两个不同的连接会尝试插入相同的记录(基于主键),但是如果两个并行连接尝试插入会导致 PK 违规的记录怎么办?

如果两个连接试图将相同的记录插入到一​​个唯一索引中,一个将被另一个连接阻塞。当第一个释放其排他锁时,第二个将抛出唯一性冲突错误(除非IGNORE_DUP_KEY目标索引上存在深奥的选项)。

如果我们要求 SQL Server 2008 与 2017,上述问题的答案是否不同?

没有本质区别。SQL Server 2016 及更高版本可以在没有跟踪标志 610 的情况下实现对索引的最少日志批量插入。


在实践中,使用一个(或多个)b-tree 索引实现对表的真正并发批量插入可能很棘手。您可能需要禁用目标的锁升级和/或采取其他操作。当存在多个索引时,这是一项更复杂的工作。有关更多详细信息,请参阅数据加载性能指南