在存储过程中缓存动态sql

时间:2013-04-01 23:03:45

标签: 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), 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

2 个答案:

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

答案 1 :(得分:1)

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

存储过程计划缓存在内存而非磁盘上的事实意味着它将在服务器重新启动时或由于重复使用率较低而退出缓存。如果过程所依赖的数据变化足以导致统计信息无效,它也可能会脱离缓存。这会导致SQL Server使计划无效。

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

SELECT sc.*
FROM master.dbo.syscacheobjects AS sc
WHERE sc.cacheobjtype = 'Executable Plan'
相关问题