Pau*_*ams 11 sql-server concurrency sql-server-2012 wait-types
我们有一个生成库存报告的流程。在客户端,进程拆分可配置数量的工作线程,为报告构建一个数据块,该数据块对应于许多商店中的一个(可能是数千个,通常是数十个)。每个工作线程调用一个执行存储过程的 Web 服务。
处理每个块的数据库进程将一堆数据收集到一个#Temporary 表中。在每个处理块结束时,数据将写入 tempdb 中的永久表。最后,在进程结束时,客户端的一个线程从永久 tempdb 表中请求所有数据。
运行此报告的用户越多,它的速度就越慢。我分析了数据库中的活动。有一次,我看到 35 个单独的请求在过程中的某一点都被阻止了。所有这些 SPIDLATCH_EX对资源类型的等待时间大约为 50 毫秒METADATA_SEQUENCE_GENERATOR (00000010E13CA1A8)。一个 SPID 拥有此资源,而所有其他 SPID 都处于阻塞状态。我在网络搜索中没有找到有关此等待资源的任何信息。
我们正在使用的 tempdb 中的表确实有一IDENTITY(1,1)列。这些 SPID 是否在等待 IDENTITY 列?我们可以使用哪些方法来减少或消除阻塞?
服务器是集群的一部分。服务器在 64 位 Windows 2008 R2 Enterprise 上运行 64 位 SQL Server 2012 Standard Edition SP1。服务器有 64 GB RAM 和 48 个处理器,但数据库只能使用 16 个,因为它是标准版。
(请注意,我对在 tempdb 中使用永久表来保存所有这些数据的设计并不感到兴奋。改变这将是一个有趣的技术和政治挑战,但我愿意接受建议。)
更新 4/23/2013
我们已经与 Microsoft 建立了一个支持案例。随着我们了解更多,我会更新这个问题。
更新 5/10/2013
SQL Server 支持工程师同意等待是由 IDENTITY 列引起的。删除 IDENTITY 消除了等待。我们无法在 SQL 2008 R2 上复制该问题;它仅发生在 SQL 2012 上。
(2019 年 2 月更新)
这是一篇旧帖子,它说我终于设法说服微软,这种情况发生的事实确实是一个缺陷。
更新: MS 确认了该缺陷并为其分配了错误编号 12628722。
我在 2018 年 11 月看过这篇文章,当时我们从 Sql Server 2005 升级到 Sql Server 2017 后开始遭受同样的痛苦。 一个 330 万行的表,过去需要 10 秒才能进行批量插入突然开始需要 10带有Identity列的表的分钟数。
事实证明,这背后有两个问题:
我花了 4 周时间,但就在假期过后,我收到了圣诞老人送来的迟来的礼物——确认问题确实是一个缺陷。
在解决此问题之前,我们发现了一些可能的解决方法:
Option (MaxDop 1)在查询中使用将批量插入转换回序列化计划。Select Cast(MyIdentityColumn As Integer) As MyIdentityColumn)
SELECT...INTO更新:
MS 将实施的修复将是将这些类型的插入返回到使用 Serialized 计划。这是为Sql Server 2017 CU14计划的(没有关于 Sql Server 其他版本的消息 - 抱歉!)。在实施时,跟踪标志9492将需要打开,无论是在服务器级别,或通过 DBCC TraceOn。
假设您可以将问题隔离到标识值的生成(尝试删除该列作为测试),我建议是这样的:
IDENTITY从最终表的列中删除该属性。因此,如果您的商店 id 为 3 和 4,则最终的 id 值将如下所示:
3000000001
3000000002
3000000003
...
4000000001
4000000002
...
Run Code Online (Sandbox Code Playgroud)
或者类似的东西。你明白了。
这将消除在生成时序列化的需要IDENTITY,同时保留最终结果的唯一性。
或者,根据流程的工作方式,将最终计算的 id 值插入#Temporary 表中。然后,您可以创建一个将它们组合在一起的视图UNION ALL,从而根本不需要复制数据。