简体   繁体   English

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

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

I've got the a SQL Server stored procedure with the following T-SQL code contained within: 我有一个包含以下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

It's that "dynamic" WHERE clause that is bothering me. 正是“动态” WHERE子句困扰着我。 The user doesn't have to pass in every parameter to this stored procedure. 用户不必将每个参数都传递给此存储过程。 Just the ones that they are interested in using as a filter for the output. 只是他们感兴趣的那些用作输出的过滤器。

How would I go about using SQL Server Studio or Profiler to test whether or not this store procedure is recompiling every time? 我将如何使用SQL Server Studio或Profiler来测试此存储过程是否每次都在重新编译?

Just offhand, you can simplify these: 临时而言,您可以简化以下步骤:

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

to this: 对此:

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

As far as the recompile - is it declared WITH RECOMPILE ? 至于重新编译-是否用WITH RECOMPILE声明?

The following article explains how to find out if your stored procedure is recompiling: http://it.toolbox.com/blogs/programming-life/sql-performance-abnormal-stored-procedure-recompiles-8105 以下文章介绍了如何确定存储过程是否正在重新编译: http : //it.toolbox.com/blogs/programming-life/sql-performance-abnormal-stored-procedure-recompiles-8105

Here's a quote from the appropriate section: 这是适当部分的引文:

start SQL Profiler and start a new trace, connect to our server and give an appropriate trace name, select the events tab and remove the already existing events on the "Selected event classes" list box. 启动SQL事件探查器并开始新的跟踪,连接到我们的服务器并提供适当的跟踪名称,选择“事件”选项卡,然后在“选定的事件类”列表框中删除已经存在的事件。 Now choose the "Stored Procedures" node in the "Available event classes" and add SPComplete, SPRecompile, SPStarting, SP:StmtStarting and SP:StmtCompleted. 现在,在“可用事件类”中选择“存储过程”节点,然后添加SPComplete,SPRecompile,SPStarting,SP:StmtStarting和SP:StmtCompleted。 Now choose the "data columns" tab and select just about the right amount of events and data columns that you need. 现在,选择“数据列”选项卡,然后选择所需数量的事件和数据列。 Add filters to reduce the number of events you collect. 添加过滤器以减少收集的事件数。

I would filter by the name of your stored procedure. 我将按您的存储过程的名称进行过滤。

Your inserting into a temp table in your example which causes the SP to be recompiled every time because it cannot be precompiled. 您在示例中插入临时表会导致SP每次都被重新编译,因为它无法预编译。

This is one of the differences between using temp tables and table variables - a good article on the differences can be found here 这是使用临时表和表变量之间的差异之一-可以在此处找到有关差异的好文章

Pertinent extract... 相关提取物...

The second major difference is that any procedure with a temporary table cannot be pre-compiled, while an execution plan of procedures with table-variables can be statically compiled in advance. 第二个主要区别是,带有临时表的任何过程都不能预先编译,而带有表变量的过程的执行计划可以事先进行静态编译。 Pre-compiling a script gives a major advantage to its speed of execution. 预编译脚本的主要优势在于执行速度。 This advantage can be dramatic for long procedures, where recompilation can be too pricy. 对于重新编译过于昂贵的长程序而言,此优势可能非常明显。

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

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