需要定期删除并重新创建存储过程?

Need to periodically drop and recreate stored procedure?

这是我的问题。我正在使用 SQL Server 2014。我有一个 ASP.Net 网络应用程序,它接受来自用户的字符串。该字符串被传递到一个存储过程 (SP),该存储过程查询一个视图,该视图查询一个链接服务器。我的数据访问层 returns 一个数据 table 到我的业务对象。如果有数据 - 输入的字符串被认为是有效的(它在链接服务器上有匹配)。如果没有数据,则认为输入的字符串无效(链接服务器上没有匹配项)。

很简单,这里是信息的路径:

WebApp - 存储过程 - 视图 - 链接服务器 - Table 有数据

显然,一旦执行查询,这条路径就会反转(数据从 table 传递到网络应用程序)。

这就是奇怪的地方。自 SP 创建以来的过去 13 个月中有两次(今天是第二次),在输入 VALID 字符串时没有数据返回到 Web 应用程序。需要明确的是,这个 SP 一直有效(除了这两次)。但是,一旦它失败,它就永远无法工作,直到它被删除并重新创建。

所以,这是可行的:

这是行不通的:

真正非常奇怪的部分:

这两次都发生了,删除并重新创建存储过程解决了问题。 SP 会工作几个月,然后就停止工作,这是怎么回事?那么解决方法是如何删除并重新创建 SP?

首先,为什么会这样?还有许多其他 Web 应用程序调用 SP,调用视图,调用从未失败的 SAME 链接服务器。但是一年两次,ONE SP 无故失败 - 删除并重新创建它解决了问题?

请帮忙 - 这真的很令人困惑...如果您需要更多信息,请告诉我。

编辑

回复 alroc 的评论:

第二次编辑

回复 beercohol 的评论:

我没有经历过您所描述的确切场景,但我处理过一个实例,尽管对基础数据进行了微不足道的更改,但存储过程偶尔会启动 运行 非常缓慢。问题原来是 SQL 服务器 "parameter sniffing" 的一个功能。此功能使用编译过程时传递的参数来确定缓存以供将来调用的执行计划。

如果将不同的参数传递给过程会显着影响生成的执行计划,则参数嗅探可能会产生不良影响。您经常会在 'search' 过程中发现这一点,这些过程采用大量参数,其中只有少数参数用于任何给定调用。

我的解决方案是通过为每个参数声明一个局部变量并复制值来禁用参数嗅探功能。然后使用局部变量代替其余过程的参数。这足以防止优化器在确定执行计划时使用原始参数值。

此问题已解决。添加 WITH RECOMPILE 已永久解决该问题。我与另一位软件开发人员交谈,他告诉我 SQL 中存在一个错误,导致缓存的性能计划随着时间的推移开始执行得越来越差。它仍然没有解释为什么这只发生在某些存储过程而不是全部 - 但是,无论如何,强制它们在执行时重新编译是可行的!

然而,对于要求很高的 SP,这不是一个可行的选择,因为您不想重新编译它无数次 - 但就我的目的而言,它工作得很好。