在存储过程中缓存动态sql

在存储过程中缓存动态sql,sql,sql-server,tsql,Sql,Sql Server,Tsql,我在存储过程中有动态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), NE

我在存储过程中有动态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

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

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()创建一个新表,因此每次都会得到一个单独的计划。

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

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

您可以通过以下查询检查创建的执行计划:

SELECT sc.*
FROM master.dbo.syscacheobjects AS sc
WHERE sc.cacheobjtype = 'Executable Plan'

我认为它不会被缓存。此外,为每个客户创建一个新表可能是不明智的。