簡體   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