0

场景:我们有一个简单的选择查询

Declare P@

SELECT TOP(1) USERID
FROM table
WHERE non_clusteredindex_column = (@P) ORDER BY PK_column DESC

自 1 年以来,它通常在 0.12 秒内执行。但昨天午夜过后,它突然开始消耗我所有的 CPU 并需要 150 秒才能执行。我检查了 SP_who2 并没有发现死锁,除了这个消耗所有 CPU 的查询之外什么也没有。我决定重新启动服务器以消除任何参数嗅探问题或终止任何陈旧的连接。在重新启动服务器以进行未来根本原因分析之前,我进行了 SLQ 分析器跟踪 1 分钟。重启后,一切恢复正常。我很惊讶并好奇地开始查看我采用的分析器中的执行计划,并将其与 SAME 查询的当前执行计划进行比较。我发现两者都不一样。

问题之夜前的执行计划与重启后的执行计划相同。(做完美的索引寻求

但是有问题的 Night SQL 分析器中的执行计划正在执行完整的索引扫描,这会占用所有 CPU 并需要 150 秒才能执行。

问题

我可以说执行计划突然重新编译或查询在昨天午夜之后开始使用新的执行计划(完全扫描),在我重新启动后,它再次开始使用旧的和良好的执行计划(索引搜索)。

Q1。是什么让 SQL server 突然使用新的 EXECUTION 计划? Q2。是什么让 SQL Server 在重新启动后使用旧的和好的执行计划? 第三季度。当我传递参数时,任何与参数嗅探相关的东西。但从技术上讲,它不应该像参数列那样组织良好,数据分布均匀。

4

2 回答 2

0

听起来您遇到了参数嗅探问题。我看不到您的数据,但我们经常发现,即使在简单的查询场景中,当许多行与参数结果匹配并且它翻转到扫描时,即使它不应该或数据存在其他问题,例如许多值是唯一的,但他们在某些情况下决定该列在表的大部分中应该有一个 0,从而将所有内容都抛出一个循环。如果来自代码的查询运行缓慢,但您可以从 ssms 执行测试过程,这是一个非常大的危险信号,表明这条线是您的问题。

您是正确的,SQL 重新启动会刷新所有计划缓存,或者您可以手动刷新所有计划,但您绝对不想使用此方法修复单个过程的计划。一个快速的解决方法是您可以执行 EXEC sp_recompile 'dbo.procname'; 强制它只刷新一个过程执行计划并创建一个新的。重做所有计划,尤其是在繁忙的数据库中可能会导致其他 proc 的严重性能问题,并且重新启动当然会有一些停机时间。这只是在问题出现时暂时解决问题,但如果您确定了导致问​​题的参数,我会考虑考虑添加一个优化未知提示,专门为已识别的参数嗅探问题而设计。

于 2019-04-28T16:28:22.257 回答
0

在您的情况下,您可以执行以下操作:

- 在您的数据库设置中激活查询存储选项。将操作模式设置为开。

在此处输入图像描述

-- 这将开始为每个请求捕获查询计划。

-- 可以开始跟踪消耗大量资源的查询

-- 最后你可以强制一个执行计划用于这个查询

在此处输入图像描述

于 2020-01-15T11:32:21.067 回答