最近遇到了一个问题就是 一个执行速度很快的存储过程,在代码中调用的时候却超时了。
后来看到了两篇文章:
其中一篇是这样介绍的
今天同事用代码调用存储过程时超时,在SQL Server Management Studio里运行却很快就有结果,这和我上次遇到的情况一下,现在将解决方案记录如下,谨为大家作一提醒。
解决方案就是: 把存储过程中多余的空格删掉。
瞠目吧结舌吧,不过这就是现实,现实是残酷的,现实是无情的,哈哈
不一定是哪个空格就引起了超时,试着看吧
上面的解决方案是将存储过程里的空格去掉,但如果这样,存储过程的格式就不是很友好后期维护也是很麻烦。
痛定思痛,于是乎有了下面的解决方案:即然是在数据库里执行成功,所以在程序里构造一条如下的SQL执行 SqlParameter param = new SqlParameter("@project_id", project_id);
string selectCmd = string.Format("exec dbo.[***Get*ro*ctCo***] @project_id ", project_id);
DataSet ds = this.ExecuteQuery(CommandType.Text, selectCmd, param);将存储过程的执行作为一条SQL传到数据库中执行。
OK,纠结的你,赶紧试试吧。。。
而第二篇道出了问题的本质:
立即在查询分析器上执行:
exec sp_recompile @objname=‘存储过程名称‘
由于存储过程是预编译的, 在第一次执行的时候, 会生成执行计划, 以后执行的时候, 会使用这个执行计划(除非存储过程侯或者显示指定重新编译), 而不是每次执行时都去生成执行计划。
当存储过程涉及的对象结构调整, 或者相关的数据产生了很大变化, 这可能导致原来的计划不适合当前的现状(执行计划过期), 这种情况下应该重新编译存储过程。
其实如果我们在存储过程中加上 with Recompile 也会达到同样的效果