我有一些与SQL Server 2012数据库通信的.NET应用程序。
通常它从客户端获取请求,运行一些SQL查询来处理请求并返回结果。为了优化性能,我在启动时准备好所有查询,然后每次都执行准备好的语句。这在大多数时候都很好用,但偶尔我会遇到一些奇怪的性能故障,所以我试着在探查器的帮助下调查发生了什么。
我抓住了 Showplan XML Statistics Profile 和 RPC:Completed 事件。
当应用程序正常运行时,我可以在分析器中看到,在启动时它会执行如下操作:
declare @p1 int
set @p1 = 5
exec sp_prepexec @p1 output, N'@my_param_list', N'select my_field from my_table'
然后在每个客户端请求上:
exec sp_execute 5, @myparam1=value1, @myparam2=value2 ...
在此 RPC:已完成行之前,我可以看到具有相当正常执行计划的 Showplan XML Statistics Profile 事件。查询的持续时间约为50毫秒,这很好。
现在,当问题发生时,我可以在分析器中看到大约2500(!)行的 Showplan XML Statistics Profile 事件 - 每个事件都在参与其中一个表上进行了一些无意义的索引扫描。查询(唯一的区别是参与扫描的索引),后跟“Stream Aggregate”。在所有这些行之后,我终于可以看到带有以下文本的 RPC:Completed 事件:
declare @p1 int
set @p1 = NULL
exec sp_prepexec @p1 output, N'@my_param_list', N'select my_field from my_table'
且持续时间超过 30秒。我无法理解为什么需要这么长时间,所有这些扫描的含义是什么,以及sp_prepexec
中处理程序为NULL的原因。在我看来,SQL Server非常努力地执行准备好的语句,而不是放弃它或者可能尝试重新准备它。
所以我很乐意得到一个解释,这个问题和发生的事情是什么......提前感谢,并为长期解释感到抱歉。