2016-02-24 16 views
0

这是我的问题。我正在使用SQL Server 2014.我有一个ASP.Net Web应用程序,它接受来自用户的字符串。该字符串被传递给存储过程(SP),该存储过程查询查询链接服务器的视图。我的数据访问层向我的业务对象返回一个数据表。如果有数据 - 输入的字符串被认为是有效的(它在链接的服务器上有匹配)。如果没有数据,输入的字符串被认为是无效的(链接服务器上没有匹配)。需要定期删除并重新创建存储过程?

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

Web应用程序 - 存储过程 - 视图 - 链接服务器 - 表数据

显然,这条道路是相反的,一旦执行查询(和数据传递从表格并最终到网络应用程序)。

这里是它变得奇怪。自创建SP(今天是第二次)以来,在过去13个月中曾两次没有数据在VALID字符串输入时返回到Web应用程序。要清楚的是,这个SP总是有效(除了这两次)。但是,一旦失败,它就不会运行,直到它被丢弃并重新创建。

所以,这里是什么工作:

  • 查询链接服务器,直接,并添加字符串到 WHERE子句。
  • 直接查询视图,并将字符串添加到WHERE 子句中。

这里是行不通:

  • 输入串入网络的应用程序。
  • 直接查询SP,并将字符串作为参数传递。

而且真的,真的很怪异的一部分:

两次出现这种情况,删除并重新创建存储过程解决了这个问题。 SP如何运行数月,然后停止工作?那么如何解决这个问题呢就是放弃并重新创建SP?

首先,这是为什么发生?还有很多其他的Web应用程序调用SP,它们调用视图,调用从未失败的SAME链接服务器。但一年两次ONE SP失败没有明显的原因 - 删除并重新创建它解决了这个问题?

请帮忙 - 这真是令人困惑......请让我知道你是否需要更多信息。

编辑

针对alroc的评论:

  • 创建存储过程并没有什么 做安全的脚本。任何可以访问数据库的用户都可以访问SP。
  • 我是这里唯一的DBA,所以没有其他人“应该”更改DB上的任何 安全或权限。但是,如果他们在做 ,那么我会在其他地方预期这些问题,因为网络应用程序 使用相同的SQL登录(相同的连接字符串),适用于每个其他进程的 - 并且有数百个。

第二个编辑

针对beercohol的评论:

  • 查询不超时 - 它不返回任何结果几乎瞬间。 超时设置为30秒,接近 的阈值接近此阈值。
  • 我运行了DBCC CheckDB,没有发现错误。
  • 我会在下次发生这种情况时尝试重新编译SP,但为什么执行计划会定期对数百或数千个SP中的某个SP执行失败?
+0

创建SP的脚本是否也授予与其相关的任何安全性?如果是这样,是否有人可能会“修复”安全性,并在这个过程中撤销你的SP所依赖的东西? – alroc

+0

@alroc我编辑了我的答案以回应您的评论。 –

+0

我会检查两件事 - 1)你确定查询在返回“无数据”时没有超时? 2)运行DBCC CHECKDB检查数据库是否损坏。 – beercohol

回答

0

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

然而,这对于一个高度要求的SP来说不是一个可行的选择,因为你不想重新编译一次巨大的代码 - 但对我的目的来说,它工作得很好。

1

我还没有经历过您描述的确切场景,但我已经处理了一个存储过程偶尔会开始以极慢的速度运行的实例,尽管基础数据的变化不大。问题原来是SQL Server的一个称为“参数嗅探”的功能。此功能使用在编译过程时传递的参数来确定为将来调用而缓存的执行计划。

如果向过程传递不同的参数可能会显着影响生成的执行计划,则参数嗅探会产生不良影响。你会经常用'搜索'程序来找到这个程序,它需要大量的参数,其中只有少数参数用于任何给定的调用。

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

+0

是的,我知道参数嗅探,并在过去听说过类似的问题。我很感谢你的回应,但这绝对不是问题。该SP有一个参数 - 并且该值绝不影响执行计划或性能,因为链接的服务器不在该列上编制索引。 –

+1

同意 - 听起来不像这是你的问题。我没有任何其他建议,但我会在这里保留这个答案,以防万一任何人在页面上遇到与相关问题发生冲突。 – Stefan