1

我在存储过程中有动态 SQL,它创建动态表并插入数据。我的问题是,这个查询计划是否会被缓存。

这是我当前如何在存储过程中构建动态 SQL 的简单示例。

CREATE PROCEDURE [dbo].[GetOrders] 
@CustID AS INT
AS 

BEGIN

DECLARE @SQL NVARCHAR(MAX) 

DECLARE @TableName AS VARCHAR(500)

    SET @TableName = CONVERT(VARCHAR(255), NEWID())

    SET @SQL = 'CREATE TABLE [dbo].[' + @TableName + ']
(
  [OrderID] [int] NOT NULL
) '

    EXEC sp_executesql @SQL

    SET @SQL = 'insert [dbo].[' + @TableName + '](OrderID) 
            select OrderID from dbo.Orders where CustomerID=@CustID'

    EXEC sp_executesql @SQL, N'@CustID INT', @CustID = @CustID


 END
 GO
4

2 回答 2

1

是的,这个查询计划将被缓存。您可以通过运行代码然后立即运行此查询来看到这一点:

SELECT *
FROM sys.dm_exec_query_stats s
CROSS APPLY sys.dm_exec_query_plan(s.plan_handle) qp
WHERE creation_time >= DATEADD(SECOND, -10, GETDATE())

由于您每次都基于 NEWID() 创建一个新表,因此您每次都会获得一个单独的计划。

于 2013-04-01T23:20:06.940 回答
1

是的,执行计划将在第一次执行时创建并缓存在内存(而不是磁盘)中。当您为每个查询创建一个新表时,我认为该计划不会被重用,但我尚未对此进行测试。

存储过程计划缓存在内存中而不是磁盘上的事实意味着它会在服务器重新启动时或由于低重用率而从缓存中消失。如果过程所依赖的数据变化到足以导致统计信息失效,它也可能会从缓存中掉出来。这会导致 SQL Server 使计划无效。

您可以检查使用以下查询创建的执行计划:

SELECT sc.*
FROM master.dbo.syscacheobjects AS sc
WHERE sc.cacheobjtype = 'Executable Plan'
于 2013-04-01T23:22:08.603 回答