sp_prepexec (sp_execute) 与 sp_executeSQL

J.T*_*.T. 8 sql-server stored-procedures dynamic-sql prepared-statement temporary-tables

问题的核心:实际存储过程是实现临时表缓存的唯一机制还是系统存储过程(例如sp_executeSQL/sp_execute也利用它们)?

我不是 DBA,所以请少说几句。我们的应用程序发送准备好的语句,从分析器中,我看到运行所有 SQL,sp_prepexec它是运行sp_preparesp_execute. 我想要做的是弄清楚我是否从临时表缓存中受益。

我一直在使用带有 object_id() 的本指南来检查行为

https://sqlkiwi.blogspot.com/2012/08/temporary-tables-in-stored-procedures.html

然后这篇博文中的第 3 点表明 EXEC 不能使用临时表缓存,但忽略了 sp_executeSQL 是否可以:http : //blogs.msdn.com/b/turgays/archive/2013/09/18/exec-vs- sp-executesql.aspx

在我通过客户端发送的查询中,我创建了一个简单的临时表。

DECLARE @foo int; -- set by JDBC, unused but required to force a prepared statement

SELECT 1 AS id
    INTO #tmp

SELECT OBJECT_ID('tempdb..#tmp');
Run Code Online (Sandbox Code Playgroud)

在探查器中,我可以看到:

declare @p1 int
set @p1=NULL
exec sp_prepexec @p1 output,N'@P1 int',N'declare @foo INT = @P1 

SELECT 1 as id
    into #tmp

select Object_id(''tempdb..#tmp'');
DROP TABLE #tmp;',1
select @p1
Run Code Online (Sandbox Code Playgroud)

我也从中得到了一个缓存命中。但是,临时表的 object_id 似乎在我身上发生变化,如果这个临时表是在真正的存储过程中创建的,我不会看到这种行为。但是,当我通过 运行相同的代码时sp_executeSQL,我还看到临时表的 object_id 已更改。这让我相信只有“真正的”用户创建的存储过程才能利用临时表缓存。

Pau*_*ite 9

实际存储过程是实现临时表缓存的唯一机制还是系统存储过程(例如sp_executeSQL/sp_execute也利用它们)?

您需要一个真正的存储过程 ( CREATE PROCEDURE) 才能从临时表缓存中受益。这包括临时存储过程 ( #procname)。

这篇博文中的第 3 点表明 EXEC 不能使用临时表缓存,但忽略了 sp_executeSQL 是否可以。

请注意,EXECUTE用于运行sp_executesql.

测试:有很多方法可以检查是否正在发生缓存。其中一些列在我在问题中引用的原始文章中,在我的后续文章Temporary Table Caching Explained中显示了更多方法,例如:

SELECT 
    DOMCC.name,
    DOMCC.pages_kb,
    DOMCC.pages_in_use_kb,
    DOMCC.entries_count,
    DOMCC.entries_in_use_count
FROM sys.dm_os_memory_cache_counters AS DOMCC
WHERE DOMCC.[type] = N'CACHESTORE_TEMPTABLES';
Run Code Online (Sandbox Code Playgroud)

存储过程输入 TVP 也被缓存,从 SQL Server 2012 开始,当与sp_executesql. 有关详细信息,请参阅链接的 CSS 博客文章。