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--临时表的缓存

时间: 2024-08-01 22:30:26

TempDB--临时表的缓存的相关文章

Sql Server tempdb原理-缓存机制解析实践

Tempdb就像Sqlserver的临时仓库,各式各样的对象,数据在里面进行频繁计算,操作.大量的操作使得tempdb可能面临很大压力,tempdb中缓存的设计就是为了缓解这些压力.这次就为大家介绍下tempdb的缓存机制. 在介绍缓存机制前,先简单了解一下TempDB对象 一般我们把tempdb对象分为两种类型用户对象和内部对象.用户对象指通过显式T-sql来创造的对象(如临时表),内部对象指通过隐式T-sql创建的对象(Worktables) 注:在引入版本控制后,也可以此单独分类(DMV

SQL Server数据库的存储过程中定义的临时表,真的有必要显式删除(drop table #tableName)吗?

本文出处:http://www.cnblogs.com/wy123/p/6704619.html 问题背景 在写SQL Server存储过程中,如果存储过程中定义了临时表,有些人习惯在存储过程结束的时候一个一个显式地删除过程中定义的临时表(drop table #tName),有些人又没有这个习惯,对于不明真相的群众或者喜欢思考的人会问,存储过程中定义的临时表,最后要不要主动删除,为什么?或者说是不是存储过程结束的时候删除临时表更加规范?不止一个人问过这个问题了,说实在话,本人之前确实不清楚,只

SQLSERVER Tempdb的作用及优化

tempdb 系统数据库是可供连接到 SQL Server 实例的所有用户使用的全局资源.tempdb 数据库用于存储下列对象:用户对象.内部对象和版本存储区. 用户对象 用户对象由用户显式创建.这些对象可以位于用户会话的作用域中,也可位于创建对象所用例程的作用域中.例程可以是存储过程.触发器或用户定义函数.用户对象可以是下列项之一: 用户定义的表和索引 系统表和索引 全局临时表和索引 局部临时表和索引 table 变量 表值函数中返回的表 内部对象 内部对象是根据需要由 SQL Server

SqlServer——临时表和表变量

一.临时表概述 SqlServer临时表有两种:局部临时表.全局临时表. 1.临时表的共同特点: 无论会话的数据库上下文如何,临时表都被保存到 tempdb 数据库中: 当临时表数据较少时,页被保存到内存中:内存不足时,才持久化临时表的页: 判断临时表是否存在:if object_id('tempdb..#临时表名','U') N) is not null print '存在'; 2.临时表之间的区别 局部临时表: 临时表名前以#开头,临时表由创建该表的会话所有,为实现不同会话之间同名的临时表相

sql server 判断是否存在数据库,表,列,视图

1 判断数据库是否存在if exists (select * from sys.databases where name = '数据库名')    drop database [数据库名] 2 判断表是否存在if exists (select * from sysobjects where id = object_id(N'[表名]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)    drop table [表名] 3 判断存储过程是否存在if ex

SQL中if exists用法细节

用if exists建表[转] 1 判断数据库是否存在 Sql代码 if exists (select * from sys.databases where name = ’数据库名’) drop database [数据库名]  if exists (select * from sys.databases where name = ’数据库名’) drop database [数据库名] 2 判断表是否存在 Sql代码 if exists (select * from sysobjects w

SQL Server判断对象是否存在 (if exists (select * from sysobjects )(转)

1 判断数据库是否存在Sql代码 if exists (select * from sys.databases where name = '数据库名')    drop database [数据库名]  if exists (select * from sys.databases where name = '数据库名')  drop database [数据库名]2 判断表是否存在Sql代码 if exists (select * from sysobjects where id = objec

百度复制SQL语句

本词条从基础知识.判断对象和应用技巧等方面,介绍了SQL(Structured Query Language)结构化查询语言的应用方法. 目录 1基础 ? 创建数据库? 删除数据库? 备份sql server? 创建新表? 创建序列? 删除表? 删除表中信息? 增加一个列? 删除一个列? 添加主键? 创建索引? 创建视图? 基本的sql语句 2最新语句 ? 高级查询? 外连接 3判断对象 ? 判断数据库是否存在? 判断表是否存在? 判断存储过程是否存在? 判断临时表是否存在? 判断视图是否存在?

【JDBC】深入理解Statement和PreparedStatement

一.使用Statement而不是PreparedStatement对象 JDBC驱动的最佳化是基于使用的是什么功能. 选择PreparedStatement还是Statement取决于你要怎么使用它们. 对于只执行一次的SQL语句选择Statement是最好的. 相反, 如果SQL语句被多次执行选用PreparedStatement是最好的.PreparedStatement的第一次执行消耗是很高的. 它的性能体现在后面的重复执行. 例如, 假设我使用Employee ID, 使用prepare

判断数据库表、试图、存储过程等是否存在

1 判断数据库是否存在 if exists (select * from sys.databases where name = '数据库名')    drop database [数据库名] 2 判断表是否存在 if exists (select * from sysobjects where id = object_id(N'[表名]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)    drop table [表名] 3 判断存储过程是否存在 if