由于从多个数据库创建高并发临时表而导致对 tempdb 的争用?

Zap*_*002 4 sql-server concurrency tempdb blocking sql-server-2017

我有一个包含约 100 个数据库的环境,所有数据库都具有相同的架构。每个数据库上都有一个存储过程,它创建一个#temp 表并删除它,并且运行非常频繁(每个用户每 30 秒左右,并且有 1000 多个用户)。它的作用远不止于此:我们正在将潜在的数千行加载到这个临时表中,然后将整个内容转储出来,基本上它聚合了一堆数据。

由于所有数据库都创建相同的临时表,它们是否都相互竞争?还是每个数据库都在 tempdb 中获得了自己的临时表版本?

似乎他们有争用,因为我看到大量PAGE_LATCH等待,都在 tempdb ( 2:3:1041580)的同一页面上,这不是 GAM、SGAM 或 PFS 页面,并且 90% 的等待似乎来自同一个页面跨所有数据库的存储过程。这些等待占服务器总等待的 90%,并导致阻塞。

我做了一个DBCC PAGE,它似乎是sysobjvalues(来自标题中的 object_ID 60)。我跑了:

SELECT OBJECT_Name(object_ID), * 
FROM sys.dm_db_database_page_allocations(2,60,NULL,NULL,'DETAILED')
Run Code Online (Sandbox Code Playgroud)

我得到 153 行,不确定我在这里看到的是什么。看起来像它IN_ROW_DATALOB_DATAallocation_unit_type_desc

我在与其他文件不同的卷上有 8 个 tempdb 文件。我有 16 个内核,但我的理解是,由于它不是分配页面,因此可能无助于增加文件数量。使用 SQL Server 2017 企业版。

我觉得最好的办法是告诉开发人员在这里删除临时表,但这需要重新处理逻辑并且需要一些时间。在等待开发修复时,我还能做些什么来避免这些页面闩锁?

Pau*_*ite 5

我们正在将潜在的数千行加载到这个临时表中,然后将整个内容转储出来,基本上它聚合了一堆数据。

如果使用得当,临时表可以极大地提高性能和可靠性。

例如,在临时表中存储相对较小(和窄)的中间结果集非常有用,这样 SQL Server 可以计算数据的自动统计信息,或者用户可以添加特定的索引。

当临时表允许优化器生成比单个整体查询更好的计划序列时,它们最有用。

临时表也可能使用不当。在“倾倒整个事物”之前简单地将行存储在临时表中听起来会适得其反。请始终牢记临时表不是免费的,可能会导致争用。

除了以合理的方式使用临时表之外,还要尝试安排一些事情,以便利用临时表缓存。有关详细信息,请参阅我的文章SQL Server 临时对象缓存

确保您正在运行最新的累积更新,因为已经采用了多项性能优化和错误修复,例如: