在 SQL Server 2016 中调试一个关于存储过程执行的奇怪场景
Posted
技术标签:
【中文标题】在 SQL Server 2016 中调试一个关于存储过程执行的奇怪场景【英文标题】:Debugging a strange scenario in SQL Server 2016 with regards to stored procedure execution 【发布时间】:2017-10-06 06:41:13 【问题描述】:在我们的组织中,我们在 Azure 上拥有 SQL Server VM,并且始终位于具有 2 个节点的可用性组中。
场景:
我们有一个名为“SP_xyz”的过程,它包含一个选择查询,其中包含很少的内部连接来获取凭证持有者列表。在一些负载之后,这个存储过程 (SP) 开始运行缓慢,因此我们对此进行了优化,并将该 SP 重新投入生产,它运行了一段时间。
几个月后随着负载的增加,这个 SP 再次出现缓慢问题,我们再次分析了这个 SP 并进行了优化。现在谜团来了,为了交叉验证新优化的 SP,我们在生产中使用 _test 创建了相同的 SP。新的 SP 是“SP_xyz_Test”。
当我们使用与旧 SP (SP_xyz) 运行缓慢的相同参数集在 prod 中运行这个新的 _Test SP 时,新优化的 SP 以毫秒为单位给出结果,而旧 SP 的结果是几秒钟。
令我们惊讶的是,当我们运行旧 SP 的下一个动作时,它也开始以毫秒为单位给出结果。这真的让我们感到害怕,因为我们有大约 300 多个 SQL 存储过程。
我们确实分析了一些我们可以想到的事情来找到根本原因:
-
索引重建
统计更新
此外,我们知道 SP 执行计划将特定于 SP 名称。但这里老的 SP 是如何变得更快是我们想知道的。
但所有这些事情都已安排好并在生产中运行,旧的 SP 开始运行缓慢。但是新的_test SP跑的动作,已经变得非常快了。
我们在这里遗漏了什么吗?以前有人遇到过这个问题吗?
【问题讨论】:
这不是我真正要求的。这是 sql server 中的 sprocs 发生的非常基本的事情。我的问题是不改变任何东西,只要在同一个数据库服务器上运行具有不同名称的优化 sp,Sp 就可以开始更快地执行。 我认为参数嗅探可能是这里的一个问题 @TT -- 对不起,如果标题没有总结。我把标题放在我能想到的地方。我会尝试修改 它发生在不同的参数集... dba.stackexchange.com/a/60180/52607 【参考方案1】:我认为您提供的详细信息尚不清楚..但是由于您使用的是 sqlserver 2016.. 您可以使用 querystore 来跟踪语句或存储过程的执行情况
随着时间的推移,一个查询可能有不同的计划,一个计划可能执行得更好,一个可能不会。所以当您启用查询存储时,您可以在回归查询部分看到所有计划随时间的变化,这可以帮助您分析为什么一个计划比另一个计划花费更多时间..至少它是一个起点..
以下是具有不同计划的查询(点表示随着时间推移的新计划)以及图表上绘制的位置表示所用时间
【讨论】:
这将有助于识别之前和之后的查询计划。但是在生产中,我们没有启用查询存储来捕获计划。所以我们没有统计数据来验证。但在此之前,是什么让我改变查询计划是我的基本问题? 查询计划更改可能由于多种原因而发生..stats 过期/stats 重新编译,表更改..重新编译提示..我知道的很少 没错,但所有这些事情都在服务器上定期发生,而且这个 SP 运行缓慢。我们用不同的名字(_test)测试了优化后的 sp 的动作变得更快了。【参考方案2】:不确定您是否得到了答案。
我想这是典型的执行计划过时的例子,因为你的过程是动态的。
试试recompile
选项。
CREATE PROCEDURE SP_xyz
WITH RECOMPILE
AS
BEGIN
.......
END
GO
【讨论】:
我们试过了,但没有运气..无论如何,即使它有效,我们如何确保在生产中需要定期重新编译多少 SP..这也不可行。因为我们不能在所有运行缓慢的 SP 中使用此选项,因为存储过程在性能方面的整个想法都会受到影响。以上是关于在 SQL Server 2016 中调试一个关于存储过程执行的奇怪场景的主要内容,如果未能解决你的问题,请参考以下文章