Caching SQL Server 2012存储过程的执行时间差异很大

Caching SQL Server 2012存储过程的执行时间差异很大,caching,stored-procedures,sql-server-2012,Caching,Stored Procedures,Sql Server 2012,我有一个只接受2个参数的简单存储过程;通过观察,第一个始终被提供,第二个始终为null,并且只有在不中断应用程序调用的情况下才存在。有一个计划的SQL代理任务,它存储存储过程执行统计信息,然后每周清除缓存的计划。还有夜间计划的作业,使用Ola Hallegren的维护过程,使用默认参数重建或重新组织索引 最近,在清除缓存之后,存储过程的执行时间有时会从正常的2-15毫秒跳到120000毫秒。在存储过程上调用sp_recompile会使执行时间恢复正常。根据SolarWinds DPA(以前的Ig

我有一个只接受2个参数的简单存储过程;通过观察,第一个始终被提供,第二个始终为null,并且只有在不中断应用程序调用的情况下才存在。有一个计划的SQL代理任务,它存储存储过程执行统计信息,然后每周清除缓存的计划。还有夜间计划的作业,使用Ola Hallegren的维护过程,使用默认参数重建或重新组织索引

最近,在清除缓存之后,存储过程的执行时间有时会从正常的2-15毫秒跳到120000毫秒。在存储过程上调用sp_recompile会使执行时间恢复正常。根据SolarWinds DPA(以前的Ignite),所有等待时间均为CPU/内存

运行Profiler,我可以复制web应用程序发出的执行调用,将其粘贴到笔记本电脑上运行的SSM中,并获得正常毫秒范围内的执行时间,而根据Profiler,应用程序的持续时间要高得多。从应用程序中花费2分钟的呼叫将在从应用程序中完成呼叫后的几秒钟内在我的笔记本电脑上在<10毫秒内完成

我希望两次执行都使用相同的缓存计划并产生相同的性能,但情况显然并非如此,而且因为我从未见过第二个参数的非null值,所以我不认为这是一个奇怪的调用,其中包含可能缓存坏计划的参数

整个存储过程代码如下所示。它的唯一目的是返回一个三行结果集,指示特定购物中心是否有任何类型为1到3的当前内容

 dbo.usp_s_mall_has_rsc_content
    @mall_id        INT,
    @base_tenant_id INT = NULL
AS

SET NOCOUNT ON;
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;

SELECT  1 AS showcase_item_type_id,
        IIF(EXISTS( SELECT  *
                    FROM    dbo.content_stream_owner AS cso
                            JOIN dbo.content_stream_data AS csd ON csd.content_stream_data_id = cso.content_stream_data_id
                            JOIN dbo.content_stream AS cs ON cs.content_stream_id = csd.content_stream_id
                            JOIN dbo.content_stream_logins AS csl
                                ON (csl.mall_id = cso.mall_id OR csl.base_tenant_id = cso.base_tenant_id)
                    WHERE   cso.mall_id = @mall_id
                            AND (@base_tenant_id IS NULL OR cso.base_tenant_id = @base_tenant_id)
                            AND csd.content_stream_id = 1
                            AND csd.end_dt > SYSDATETIME()
                            AND csd.hidden_flags = 0
                            AND cs.is_active = 1
                            AND csl.is_active = 1), 1, 0) AS has_content
UNION
SELECT  2 , IIF(EXISTS( SELECT  *
                    FROM    dbo.content_stream_owner AS cso
                            JOIN dbo.content_stream_data AS csd ON csd.content_stream_data_id = cso.content_stream_data_id
                            JOIN dbo.content_stream AS cs ON cs.content_stream_id = csd.content_stream_id
                            JOIN dbo.content_stream_logins AS csl
                                ON (csl.mall_id = cso.mall_id OR csl.base_tenant_id = cso.base_tenant_id)
                    WHERE   cso.mall_id = @mall_id
                            AND (@base_tenant_id IS NULL OR cso.base_tenant_id = @base_tenant_id)
                            AND csd.content_stream_id = 2
                            AND csd.end_dt > SYSDATETIME()
                            AND csd.hidden_flags = 0
                            AND cs.is_active = 1
                            AND csl.is_active = 1), 1, 0)
UNION
SELECT  3 , IIF(EXISTS( SELECT  *
                    FROM    dbo.content_stream_owner AS cso
                            JOIN dbo.content_stream_data AS csd ON csd.content_stream_data_id = cso.content_stream_data_id
                            JOIN dbo.content_stream AS cs ON cs.content_stream_id = csd.content_stream_id
                            JOIN dbo.content_stream_logins AS csl
                                ON (csl.mall_id = cso.mall_id OR csl.base_tenant_id = cso.base_tenant_id)
                    WHERE   cso.mall_id = @mall_id
                            AND (@base_tenant_id IS NULL OR cso.base_tenant_id = @base_tenant_id)
                            AND csd.content_stream_id = 3
                            AND csd.end_dt > SYSDATETIME()
                            AND csd.hidden_flags = 0
                            AND cs.is_active = 1
                            AND csl.is_active = 1), 1, 0);

您是否每次都尝试重新编译存储过程

ALTER PROCEDURE dbo.usp_s_mall_has_rsc_content
    @mall_id        INT,
    @base_tenant_id INT = NULL
WITH RECOMPILE
AS
...

我在一些存储过程中看到了这个问题。您在
IIF(…)
中嵌套了查询
IIF
只需要标量参数,因此SQL Server认为所有涉及的表只为
联接提供一行,并使用低效的
循环联接。当表返回数千行以参与联接时,它就会爆炸。

您是否每次都尝试重新编译存储过程

ALTER PROCEDURE dbo.usp_s_mall_has_rsc_content
    @mall_id        INT,
    @base_tenant_id INT = NULL
WITH RECOMPILE
AS
...

我在一些存储过程中看到了这个问题。您在
IIF(…)
中嵌套了查询
IIF
只需要标量参数,因此SQL Server认为所有涉及的表只为
联接提供一行,并使用低效的
循环联接。当表返回数千行以参与联接时,它就会爆炸。

当性能从一次更改到另一次时,主要是由于SQL选择的执行计划不同。重新检查索引,使用实际执行计划跟踪运行查询,以查看索引是否正确。当性能从一次更改到另一次时,主要是由于SQL选择的执行计划不同。重新检查索引,使用实际执行计划跟踪运行查询,以查看索引是否正确。当性能从一次更改到另一次时,主要是由于SQL选择的执行计划不同。重新检查索引,使用实际执行计划跟踪运行查询,查看索引是否正确。