2013-01-14 54 views
1

當我執行這個簡單的SP,然後檢查從下面的DMV查詢的查詢計劃,查詢計劃回來爲NULL。但是,如果我註釋掉SP中的else塊(或將其更改爲不引用臨時表),則DMV查詢確實會顯示查詢計劃。任何想法是什麼造成這種差異?並且NULL查詢計劃意味着什麼都沒有被緩存?我正在使用SQL Server 2008 R2。是什麼導致DMV顯示NULL查詢計劃?

CREATE PROCEDURE dbo.SampleSp 
(
    @Option TINYINT 
) 
AS 
    DECLARE @RowCount INT; 

    -- Get ID into local temp table 

    CREATE TABLE #P (ID INT PRIMARY KEY); 
    INSERT INTO #P 
    VALUES (1), (2) 

    IF @Option = 1 
    BEGIN 
     SELECT ID FROM #P 
    END 
    ELSE 
    BEGIN 
     SELECT ID FROM #P 
    END 
GO 

    --Call SP 
    EXEC dbo.SampleSp 1 
GO 
    --DMV Query to find query_plan 
    SELECT 
      CP.objtype, 
      CP.usecounts AS Ct, 
      ST.last_execution_time, 
      SUBSTRING(Text, (statement_start_offset/2) + 1, (CASE statement_end_offset WHEN -1 THEN DATALENGTH(Text) ELSE statement_end_offset END - ((statement_start_offset/2) + 1))) AS query, 
      T.text, 
      PL.query_plan 
    FROM sys.dm_exec_cached_plans AS CP WITH(NOLOCK) 
    CROSS APPLY sys.dm_exec_sql_text(CP.plan_handle) AS T 
    OUTER APPLY sys.dm_exec_query_plan(CP.plan_handle) AS PL 
    LEFT OUTER JOIN sys.dm_exec_query_stats AS ST WITH(NOLOCK) ON ST.plan_handle = CP.plan_handle 
    WHERE 1=1 
    AND ST.last_execution_time > DATEADD(MINUTE, -5, GETDATE()) 
    AND T.text LIKE '%SampleSp%' 
    AND T.text NOT LIKE '%dm_exec_cached_plans%' 
    ORDER BY ST.last_execution_time DESC 
+0

請使用DATEADD(MINUTE,-5,GETDATE()) - 日期/時間隱含的數學不會爲新的數據類型的工作,並在某些時候,這些動態管理視圖可以切換到更高的精度和您所有的疑問將打破。 –

+0

但是,回到問題,您是否啓用了「優化ad hoc工作負載」設置?也許沒有查詢計劃會回來,因爲您只運行一次查詢,並且只存儲了一個存根。 –

+0

不,不啓用對ad hoc工作負荷設置的優化。 – JohnnyM

回答

1

我相信我明白了。看來該計劃將顯示爲NULL,直到SP中的每個分支都執行完畢。 (您可以通過撥打另一個電話到SP爲2的參數值看到這一點,然後計劃並顯示出來。)如果只有部分SP已經被執行,SQL Server會緩存比計劃內(你可以看到這個通過查看usecounts,加上我做的其他更廣泛的測試來證明這一點),但它不會顯示在我已經使用的DMV查詢中。這引發了一個問題:你如何看待已經被緩存的SP部分的計劃?

+0

您是否完全確定如果您再次使用* same *參數調用該計劃,該計劃將不會顯示出來? –

+0

是的,我測試過了。你自己嘗試一下,看看。所有分支機構都已執行的時刻,它顯示了計劃。 – JohnnyM

+0

我得到的SQL 2012年的實際查詢是更復雜的結果相同(沒有查詢計劃):一些設置代碼,分支四路填補工作臨時表,然後雙向分支返回一個兩個結果集。我證實我必須使每個分支和每個末端分支都具有競爭力。但是:這整個問題消失了,當我改變了PROC臨時表(@temp),而不是tempdb數據庫(#TEMP)表 - 然後計劃總是顯示。 (撇開我是否想要@temp和#temp的問題。) –

相關問題