Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 是什么导致DMV显示空查询计划?_Sql Server_Sql Server 2008 R2 - Fatal编程技术网

Sql server 是什么导致DMV显示空查询计划?

Sql server 是什么导致DMV显示空查询计划?,sql-server,sql-server-2008-r2,Sql Server,Sql Server 2008 R2,当我执行这个简单的SP,然后从后面的DMV查询中检查查询计划时,查询计划返回为NULL。但如果我注释掉SP中的else块(或将其更改为not reference temp table),DMV查询将显示一个查询计划。知道是什么导致了这种差异吗?空查询计划是否意味着未缓存任何内容?我正在使用SQLServer2008R2 CREATE PROCEDURE dbo.SampleSp ( @Option TINYINT ) AS DECLARE @RowCount INT;

当我执行这个简单的SP,然后从后面的DMV查询中检查查询计划时,查询计划返回为NULL。但如果我注释掉SP中的else块(或将其更改为not reference temp table),DMV查询将显示一个查询计划。知道是什么导致了这种差异吗?空查询计划是否意味着未缓存任何内容?我正在使用SQLServer2008R2

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

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

请使用DATEADD(MINUTE,-5,GETDATE())-日期/时间的隐式数学对新的数据类型不起作用,在某个时候,这些DMV可能会切换到更高的精度,您的所有查询都会中断。不过,回到问题上来,您是否启用了针对特殊工作负载的
优化设置?可能没有返回任何查询计划,因为您只运行了一次查询,并且只存储了一个存根。没有,未启用“针对临时工作负载优化”设置。您是否完全确定,如果使用相同的参数再次调用该计划,该计划将不会显示?是的,我测试了它。你自己试试看。在执行所有分支的那一刻,它显示了计划。我在SQL 2012中得到了相同的结果(没有查询计划)。实际的查询要复杂得多:一些设置代码,一个用于填充工作临时表的四向分支,然后是一个用于返回两个结果集之一的双向分支。我确认我必须让它在四个分支中的每一个,以及每一个末端分支中出现。但是:当我将proc更改为临时表(@temp)而不是tempdb(#temp)表时,整个问题就消失了——然后计划总是显示出来。(撇开我想要@temp还是#temp的问题不谈。)