查询计划突然重新编译并降低性能

问题描述 投票:0回答:1

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

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之前的执行计划与Reboot之后的执行计划相同。 (做完美的指数寻求)

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

题:

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

Q1。是什么让SQL服务器突然使用新的执行计划? Q2。是什么让SQL服务器在重启后使用旧的和良好的执行计划? Q3。当我传递参数时,与参数嗅探有关的任何事情。但从技术上讲,它不应该是因为参数列使用均匀分布的数据进行良好组织。

sql sql-server sql-server-2008 sql-execution-plan query-planner
1个回答
0
投票

听起来你有一个参数嗅探问题。我无法看到您的数据,但是我们经常发现,即使在简单的查询场景中,当许多行与参数结果匹配时它们也会突然出现,即使它不应该也会翻转到扫描,或者数据存在其他问题,例如许多值都是唯一的,但他们在某种情况下决定列在表的大部分中应该为一个循环抛出所有内容。如果来自代码的查询运行缓慢但你可以从ssms执行测试程序,这是一个非常大的红旗,沿着这条线的某些东西是你的问题。

您是正确的,SQL重新启动刷新所有计划缓存,或者您可以手动清除所有计划,但您绝对不希望使用此方法来修复单个过程的计划。快速解决方法是执行EXEC sp_recompile'dbo.procname';强制它只刷新一个程序执行计划并创建一个新程序。重做所有计划,特别是在繁忙的数据库中,可能会导致其他过程的重大性能问题,重启当然会有一些停机时间。这只会暂时解决问题,但如果您确定了一个导致问题的参数,我会考虑进一步优化未知提示,专门为已经识别的参数嗅探问题而设计。但也可能确保在您的环境中正常进行一些良好的索引维护,以防导致错误的计划而不是sql引擎。

© www.soinside.com 2019 - 2024. All rights reserved.