1

当我执行这个简单的 SP 然后从随后的 DMV 查询中检查查询计划时,查询计划返回为 NULL。但是,如果我注释掉 SP 中的 else 块(或将其更改为不引用临时表),DMV 查询确实会显示查询计划。知道是什么导致了这种差异吗?NULL 查询计划是否意味着没有缓存?我正在使用 SQL Server 2008 R2。

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
4

1 回答 1

2

我相信我想通了。似乎该计划将显示为 NULL,直到 SP 中的每个分支都已执行。(您可以通过使用参数值为 2 再次调用 SP 来看到这一点,然后该计划确实出现了。)如果只执行了部分 SP,SQL Server 会在内部缓存而不是计划(您可以看到这个通过查看使用计数,以及我为证明这一点所做的一些其他更广泛的测试),但它不会出现在我使用的 DMV 查询中。这就提出了一个问题:您如何看待仅已缓存的那部分 SP 的计划?

于 2013-01-14T21:37:13.953 回答