TempDB--临时表的缓存

--==========================================================================

在博客园看到一篇文章《SQLServer Temp tables 数据疑问》,文章中问道在没有任何负载情况下,还有大量的临时表,这是为什么?

--==========================================================================

让我们来实验探索下

首先选择任何一个用户数据库,执行以下脚本:

CREATE PROCEDURE USP_TempTableTest
AS
BEGIN
    SET NOCOUNT ON;

    CREATE TABLE #TB1(C11 INT,C22 INT)
    INSERT INTO #TB1
    SELECT 1,1

    SELECT * FROM #TB1
END
GO

EXEC USP_TempTableTest

按照通用的理解,存储过程中的临时表会在调用中创建,在存储过程调用结束后释放,存储过程执行结束后,我们不应该在tempdb中找到#TB1开头的临时表。

让我们来检查下

use tempdb
go
--======================================
--查看临时表的列
SELECT OBJECT_NAME(OBJECT_ID) AS ObjName,
* FROM SYS.all_columns
WHERE OBJECT_NAME(OBJECT_ID) LIKE %#%

运行以上代码,可以很容易找到:

列名C11和C22和我们存储过程中定于的临时表列名一样,只是换了个马甲而已,别告诉我换了马甲你们就不认识”它“咯

--================================================================

解释:

上面看到的#A2206DOC这个临时表并不是我们存储过程中使用到的#TB1,但是但是两者存在一定关联。想象一下,每次存储过程执行,都需要创建和释放临时表,而创建和释放临时表又涉及到修改很多系统表的数据,而如果缓存这个临时表,那么下一次调用存储过程时,就避免创建和释放临时表所照成的资源消耗,从而达到一定的性能提升。

 专业解释:

SQL Server删除一个临时对象时,不移除该对象的条目,当再次使用时,就无须重新创建临时对象,SQL Server为临时对象缓存一个数据页和一个IAM页,并回收剩余页,如果临时表的大小超过8MB,回收会异步进行。

--==================================================================

问题1: 多个存储过程并发调用的时候怎么办?

当并发调用时,会生成多个类似的临时表”缓存“以供调用,并保证一个临时表”缓存“在一个时间点内只能被一个回话执行的存储过程访问到,在访问结束后,会清理该临时表”缓存“的数据,然后供下一个回话使用。

 

问题2: 什么样的临时表会被”缓存“

当然不是所有临时表都会被缓存,需要满足一定的条件:

1. 没有创建命名约束

2. 临时对象在创建后没有执行影响临时表的数据定义语言DDL操作(如创建索引和创建统计)

3. 没有使用动态SQL创建临时对象

4. 临时对象被创建在另一个对象的内部,如存储过程、触发器、用户自定义函数或临时对象是一个用户自定义表值函数的分会表

 --=====================================================================

 依旧妹子引狼(最近小忙,不能保证妹子质量,勿怪)

 

 

 

TempDB--临时表的缓存,古老的榕树,5-wow.com

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。