繁体   English   中英

如何确定存储过程是否每次都在重新编译?

[英]How can I determine whether or not a stored procedure is recompiling every time?

我有一个包含以下T-SQL代码的SQL Server存储过程:

insert into #results ([ID], [Action], [Success], [StartTime], [EndTime], [Process])
select
    'ID' = aa.[ActionID],
    'Action' = cast(aa.[Action] as int),
    'Success' = aa.[Success],
    'StartTime' = aa.[StartTime],
    'EndTime' = aa.[EndTime],
    'Process' = cast(aa.[Process] as int)
from
    [ApplicationActions] aa with(nolock)
where
    0 = case
            when (@loggingLevel = 0) then 0
            when (@loggingLevel = 1 and aa.[LoggingLevel] = 1) then 0
        end
    and
    1 = case
            when (@applicationID is null) then 1
            when (@applicationID is not null and aa.[ApplicationID] = @applicationID) then 1
        end
    and
    2 = case
            when (@startDate is null) then 2
            when (@startDate is not null and aa.[StartTime] >= @startDate) then 2
        end
    and
    3 = case
            when (@endDate is null) then 3
            when (@endDate is not null and aa.[StartTime] <= @endDate) then 3
        end
    and
    4 = case
            when (@success is null) then 4
            when (@success is not null and aa.[Success] = @success) then 4
        end
    and
    5 = case
            when (@process is null) then 5
            when (@process is not null and aa.[Process] = @process) then 5
        end

正是“动态” WHERE子句困扰着我。 用户不必将每个参数都传递给此存储过程。 只是他们感兴趣的那些用作输出的过滤器。

我将如何使用SQL Server Studio或Profiler来测试此存储过程是否每次都在重新编译?

临时而言,您可以简化以下步骤:

    2 = case
                    when (@startDate is null) then 2
                    when (@startDate is not null and aa.[StartTime] >= @startDate) then 2
            end

对此:

    (@startDate is null OR aa.[StartTime] >= @startDate)

至于重新编译-是否用WITH RECOMPILE声明?

以下文章介绍了如何确定存储过程是否正在重新编译: http : //it.toolbox.com/blogs/programming-life/sql-performance-abnormal-stored-procedure-recompiles-8105

这是适当部分的引文:

启动SQL事件探查器并开始新的跟踪,连接到我们的服务器并提供适当的跟踪名称,选择“事件”选项卡,然后在“选定的事件类”列表框中删除已经存在的事件。 现在,在“可用事件类”中选择“存储过程”节点,然后添加SPComplete,SPRecompile,SPStarting,SP:StmtStarting和SP:StmtCompleted。 现在,选择“数据列”选项卡,然后选择所需数量的事件和数据列。 添加过滤器以减少收集的事件数。

我将按您的存储过程的名称进行过滤。

您在示例中插入临时表会导致SP每次都被重新编译,因为它无法预编译。

这是使用临时表和表变量之间的差异之一-可以在此处找到有关差异的好文章

相关提取物...

第二个主要区别是,带有临时表的任何过程都不能预先编译,而带有表变量的过程的执行计划可以事先进行静态编译。 预编译脚本的主要优势在于执行速度。 对于重新编译过于昂贵的长程序而言,此优势可能非常明显。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM