昨天下午晚些时候,我将 4 个 tempdb 数据文件添加到现有的 4 个中,总共 8 个(SQL 服务器上的 16 个处理器)。我还预先将它们种植到接近 100% 的可用空间。
今天,我们的一位开发人员联系了我,她说昨天她正在运行一个查询,该查询将在 3-5 秒内将一组初始结果返回到 ssms 显示,整个查询将在 2-3 分钟内完成。今天查询需要 5 分钟才能完成,大约 2.5 分钟内没有结果显示在 ssms 中。
当时没有其他查询在运行。CPU 使用率很低。我反弹了服务器,没有任何改善。所以现在我想知道我的 tempdb 更改是否导致性能下降。我看不出如何,但偏执狂开始了。我运行了查询并在它执行时监视了 tempdb,它似乎根本没有使用 tempdb,我觉得这很奇怪,因为它有一个我认为使用的 GROUP BY 语句临时数据库。该表包含大约 2200 万行,查询返回大约 780 万行。
select
DATEADD(q, DATEDIFF(q, 0, MonthOfDate), 0) as Quarter
,[PartnerCD]
,[PartnerNM]
,[PartnerGRP]
,[BizMemberID]
,[MemberID]
,[BizType]
,[RateCD]
,[Rate]
,sum([MemberMonth]) as MemberQuarter
,[CurrentAge]
,[AgeAtTime] = CASE WHEN dbo.fn_CalculateAge(BirthDT, (DATEADD(q, DATEDIFF(q, 0, MonthOfDate), 0)), 'YEAR') < 0 THEN NULL ELSE dbo.fn_CalculateAge(BirthDT, (DATEADD(q, DATEDIFF(q, 0, MonthOfDate), 0)), 'YEAR') END
,AgeCategory = dbo.fn_CalculateAgeCatYrsOrdered(BirthDT, (DATEADD(q, DATEDIFF(q, 0, MonthOfDate), 0)))
,[BirthDT]
,[ZipCD]
FROM [Partner].[dbo].[Membership]
group by DATEADD(q, DATEDIFF(q, 0, MonthOfDate), 0)
,[PartnerCD]
,[PartnerNM]
,[PartnerGRP]
,[BizMemberID]
,[MemberID]
,[BizType]
,[RateCD]
,[Rate]
,[CurrentAge]
,[BirthDT]
,[ZipCD]
可能是我的更改导致性能下降还是巧合?
答对了。这就是我在评论中特别添加该条款的原因。
当您重新启动 SQL Server 服务(或显然也重新启动服务的服务器本身)时,查询计划缓存将被清除,如 Aaron Bertrand对我关于该主题的问题的回答中所述。这意味着,之前为您的查询缓存的查询计划现在已被擦除,并且当您的 SQL Server 实例开始生成新计划时(基于正在使用的表的多种因素,它们的索引方式,以及自上一个计划以来数据的统计数据如何变化)它最终采用了一个似乎效率较低的不同计划。
您可以使用 清除计划缓存中有问题
DBCC FREEPROCCACHE (the_plan_handle_of_the_bad_plan)
的查询计划。请从文档中查看此示例,了解如何获取该特定查询计划的计划句柄。重新运行查询将重新生成一个新计划,该计划可能会或可能不会成为同一个计划。如果它最终是一样的,那么你最好的行动方案实际上是对性能瓶颈进行故障排除,这在实际执行计划本身中应该是显而易见的。