我们在 SQL Server 2014 SP1 上有一个活动的 OLTP 40GB 数据库。查询速度变慢,等待 IO_Completion,Disk Queue Length 上升到 900,SQL Server 停止响应。我们尝试了什么:
重新启动实例,一分钟后它开始以同样的方式运行。
第二次重启后,我们更改了每个 tempdb 数据文件的初始大小(创建了 16 个数据文件),它开始正常工作。
注意:我们正在为中间结果集使用表变量。这些结果集非常小。
它在一个月内发生了两次。每次我手动向数据文件添加一点空间时,它就会开始正常工作。更有趣的是,我们在 SQL Server 2008 R2 和 SQL Server 2012 上的相同设置(相同的硬件、相同的文件夹和文件设置、相同的工作负载)运行良好。
请帮助我们找到一个永久的解决方案。
所有数据文件的初始大小都是相同的 1000MB,Current 每个都是 1500MB。都是一样的。每个自动增长为 100MB。在此之前,我们面临 PFS 和 GAM 页面争用,我们增加到 16 个并解决了问题。跟踪标志 1117 和 1118 均已启用。2 个 NUMA 节点上的 24 个内核。所有数据文件都在同一个卷上。简单的磁盘,没有 SAN。
实例在物理机上。使用表变量的查询和使用散列连接的查询最常产生 IO_Completion 等待。
wBob 的详细回答促使我们进行更详细的搜索。我们之前是怎么错过的:
数据库“tempdb”中文件“templog”的自动增长被用户取消或在 7704 毫秒后超时。使用 ALTER DATABASE 为此文件设置较小的 FILEGROWTH 值或明确设置新的文件大小。
每当发生此类问题时,我们都会在日志中找到这一点。我们正在将 TempDB 移动到单独的快速驱动器。
我认为您的 tempdb 碎片过多并且服务器 CPU 和磁盘设置不匹配,但让我们收集更多信息:
问题/需要更多信息
EXEC sp_configure 'max degree of parallelism'
)。如果 CPU 是六核,则服务器 maxdop 最多应为 6(根据此处),或者可以说在 OLTP 系统上更低。我通常将我的 tempdb 文件与我的服务器 DOP 保持一致,最多 8 个,但我们会继续讨论。EXEC sp_configure 'max server memory (MB)'
)。散列与 OLTP 系统中的表变量连接?这表明缺少对表变量、主表或两者的索引。您是否像这样声明表变量(没有索引)?
不要吝啬表变量定义,即使它包含的结果集很小。最好为优化器提供尽可能多的信息,以便明确说明可空性、唯一性、索引是否聚集/非聚集,例如
发布执行计划将有助于对此进行诊断。
根据此处和此处检查防止表变量缓存的代码。我认为动态 SQL 和 proc executed WITH RECOMPILE 是唯一影响表变量的。
检查 SQL Server 日志(对象资源管理器 > 管理 > SQL Server 日志)以获取消息,例如 IO 警告。
但是忘记我们认为我们知道的;创建一个重现您的问题的测试装置,并尝试减少临时文件的数量......从 1、2、4、6 等开始收集信息,以做出基于证据的决定。现在这是更难的一点,因为您的问题似乎是间歇性的,您可能无法弄乱您的 tempdb 设置,但这就是我处理这个问题的方式。
祝你好运。让我们知道您的身体情况如何。