2008-11-26 41 views
0

我有與下面的T-SQL代碼中的一個SQL Server存儲過程中包含的:WHERE子句是困擾我如何確定存儲過程是否每次重新編譯?

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 

這是「動態的」。用戶不必將每個參數傳遞給此存儲過程。只是他們感興趣的那些用作輸出的過濾器。

我將如何去使用SQL Server Studio或Profiler來測試此存儲過程是否每次重新編譯?

回答

1

下面的文章介紹瞭如何瞭解您的存儲過程重新編譯: http://it.toolbox.com/blogs/programming-life/sql-performance-abnormal-stored-procedure-recompiles-8105

下面是相應的部分報價:

啓動SQL事件探查器,並開始一個新的 痕跡,連接到我們的服務器,並給 一個適當的跟蹤名稱,選擇 事件選項卡,並刪除已選擇的事件 類別列表框中已有的事件 列表框。現在在 「可用事件類」中選擇 「存儲過程」節點,並添加 SPComplete,SPRecompile,SPStarting, SP:StmtStarting和SP:StmtCompleted。 現在選擇「數據列」選項卡,然後選擇您需要的事件和數據列的適當數量的大約 。 添加過濾器以減少您收集的 事件的數量。

我會過濾您的存儲過程的名稱。

1

只是副手,可以簡化這些:

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

1

您插入到您的示例中的臨時表中,導致SP每次都會重新編譯,因爲它無法預編譯。

這是使用臨時表與表變量之間的區別之一 - 在不同的好文章可以發現here

相關提取物...

第二個主要的區別是, 任何具有臨時表 的過程都不能預編譯,而 過程的執行計劃可能是靜態地 事先編譯的 表變量。預編譯 腳本爲其執行速度提供了主要優勢。對於較長的過程,這種優勢可能會很大,其中 重新編譯太過昂貴。

相關問題