sp_procedure_params_90_rowset 上的过度编译阻塞

dan*_*mes 15 sql-server-2008-r2 blocking

这个问题在 MSDN 上再次出现:Blocked-process-report: what is this waitresource "OBJECT: 32767:124607697:0 [COMPILE]"

我在 Profiler 中发现了这些语句。它们的持续时间都超过 3 秒。一些超过 10+。阻止活动与来自MSDN的链接相同。

调用都使用 3 部分命名。都指定了一个不同的过程,它们看起来像下面这样:

exec [db1].[sys].sp_procedure_params_90_rowset N'proc1', 1, NULL, NULL
exec [db2].[sys].sp_procedure_params_90_rowset N'proc2', 1, NULL, NULL
exec [db3].[sys].sp_procedure_params_90_rowset N'proc3', 1, NULL, NULL
exec [db4].[sys].sp_procedure_params_90_rowset N'proc4', 1, NULL, NULL
Run Code Online (Sandbox Code Playgroud)

我可以做些什么来减少这种级别的阻塞?

(编辑)我现在看到同样的事情:

exec [db1].[sys].sp_primary_keys_rowset N'view1', N'dbo'
exec [db2].[sys].sp_primary_keys_rowset N'view1', N'dbo'
exec [db3].[sys].sp_primary_keys_rowset N'view1', N'dbo'
exec [db4].[sys].sp_primary_keys_rowset N'view1', N'dbo'
Run Code Online (Sandbox Code Playgroud)

有系统性的事情正在发生,但我不知道还能做什么。调用者是通过 ADO 的 VB6。是 ADO 进行这些调用。

下面是一个被阻止的进程报告示例

 <blocked-process-report>
    <blocked-process>
        <process
            id="process5bc1288"
            taskpriority="0"
            logused="0"
            waitresource="OBJECT: 32767:124607697:0 [COMPILE]"
            waittime="28887"
            ownerId="11638114050"
            transactionname="sqlsource_transform">
            <executionStack>
                <frame
                    line="1"
                    sqlhandle="0x000000000000000000000000000000000000000000000000">
                    <sqltext>EXEC [dbo].[spAlertDetectByPoll] ':V:^RMAlert^:Z:^&amp;N&amp;#RMAlert#&amp;S&amp;#L#&amp;UID&amp;#19#&amp;AGN&amp;#1#&amp;DFC&amp;#103#^', 1</sqltext>
                </frame>
            </executionStack>
            <inputbuf>
SET NO_BROWSETABLE OFF   </inputbuf>
        </process>
    </blocked-process>
    <blocking-process>
        <process
            status="suspended"
            waitresource="OBJECT: 32767:124607697:0 [COMPILE]"
            waittime="35693"
            spid="1121"
            sbid="0"
            ecid="0"
            priority="0"
            trancount="0"
            lastbatchstarted="2013-12-16T14:45:48.960">
            <executionStack>
                <frame
                    line="1"
                    sqlhandle="0x000000000000000000000000000000000000000000000000" />
            </executionStack>
            <inputbuf>
SET NO_BROWSETABLE OFF   </inputbuf>
        </process>
    </blocking-process>
</blocked-process-report>
Run Code Online (Sandbox Code Playgroud)

pau*_*bin 4

有一篇很棒的博客文章解释了正在发生的事情。

SQL Server 允许根据其复杂性进行一定数量的编译。它将它们分为小型、中型和大型。对于大型编译,一次只能编译一个,所以假设您的所有过程都被认为很大,那么每个过程都必须串行编译。这可以解释阻塞的原因。
我认为解决这个问题可能有几种方法——考虑更多的资源(更多的CPU将允许更多的中小型查询并发,或者可能会提高中等查询的阈值)。此外,更多的内存可能会解决问题。

如果你像我们大多数人一样,那可能是不可能的。另一种选择可能是检查 ADO 调用并查看是否可以减少或分散调用数量,以便并非所有调用同时发生。在任何给定时间减少数量应该会减少您的等待时间。

如果这不起作用,请考虑修复存储过程的“编译性”。也许将它们分解成更小的块,这可能会将它们减少到小型或中型存储桶,并允许更多的并行编译。或者确定为什么每次都需要重新编译过程。看看是否可以重写它们以便不需要重新编译。最后,我会考虑使用计划指南。这些将允许预编译过程并可能节省一些时间。

希望有帮助