我看到由于编译特定存储过程时的锁定而导致阻塞(如KB 263889 中所述)。基本上,有几个进程在同一个资源“TAB:8:1044511100:0 [COMPILE]”上等待 LCK_M_X,如果我查找对象,它就是我的存储过程之一。
试图缩小为什么不缓存该过程的执行计划的范围,我发现sp_executesql的@params 参数的大小是一个因素:如果@params 超过 4000 个字符,有时执行计划会被缓存,但是如果@params 为 4000 个字符或更少,则每次都会缓存计划。
这可以通过以下过程重现:
CREATE PROCEDURE [dbo].ObviouslyAnonymizedProcedure (
@SchemaId int = Null
, @TypeDesc varchar(60) = Null
, @paramFoo varchar(100) = null
, @paramBar datetime2(4) = null
, @paramBaz numeric(4,3) = null
-- Parameter names have been changed. I added a "param" prefix and set type
-- varchar(100) to more easily get up to 4000 characters in this example.
, @paramQux varchar(100) = null
, @paramQuux …
Run Code Online (Sandbox Code Playgroud)