Tempdb数据库详细介绍

首页 | 新闻 | 交流 | 问吧 | 文档 | 手册 | 下载 | 博客

Tempdb数据库详细介绍

作者:  时间: 2011-06-11

一、Tempdb简介

       tempdbSQLServer的系统数据库一直都是SQLServer的重要组成部分,用来存储临时对象。可以简单理解tempdbSQLServer的速写板。应用程序与数据库都可以使用tempdb作为临时的数据存储区。一个实例的所有用户都共享一个Tempdb。很明显,这样的设计不是很好。当多个应用程序的数据库部署在同一台服务器上的时候,应用程序共享tempdb,如果开发人员不注意对Tempdb的使用就会造成这些数据库相互影响从而影响应用程序。

、Tempdb的特性

1、 tempdb中的任何数据在系统重新启动之后都不会持久存在。因为实际上每次SQLServer启动的时候都会重新创建tempdb。这个特性就说明tempdb不需要恢复。

2、 tempdb始终设置为“simple”的恢复模式,当你尝试修改时都会报错。也就是说已提交事务的事务日志记录在每个检查点后都标记为重用。

3、 tempdb也只能有一个filegroup,不能增加更多文件组。

4、 tempdb被用来存储三种类型的对象:用户对象,内部对象、版本存储区

、 Tempdb存储对象

1、 用户对象:局部临时表、全局临时表、表变量,这些都存储在tempdb中。局部临时表以及全局临时表就不用多说了。针对表变量是否存在tempdb中,很多人都有误解,尤其是网上有些文章简直是误人子弟。说什么表变量是在内存中创建,速度比临时表快。我们可以通过SQLServer2005引入的动态管理视图sys.dm_db_session_space_usage来查看表变量到底存在哪里。

在你的SQLServer2005或者2008上运行以下脚本:

select * from sys.dm_db_session_space_usage

where database_id = DB_ID('tempdb') AND session_id > 50

 

declare @t table (id int)

insert into @t values(2)

 

select * from sys.dm_db_session_space_usage

where database_id = DB_ID('tempdb') AND session_id > 50

结果如下:

 

  

 


从上图中可以看出使用了表变量导致tempdb分配了一页,因此表变量不是在内存中创建的。

2、 内部对象

内部对象主要是SQLServer在处理查询的时候用户临时存储数据的对象。如排序、spool、散列连接、公用表表达式查询、创建或重新生成索引、表值函数和游标

可以通过sys.dm_db_session_space_usage中的internal_object_alloc_page_count列查看每个会话分配了多少页面用于内部对象。

3、 版本存储区

SQLServer2008中很多功能都要求维护行的多个版本,版本存储区就是用来储存索引和数据行的这些不同版本的。下面功能使用了版本存储区:触发器、快照隔离和读提交快照隔离、

联机索引操作、多活动结果集。

可以通过sys.dm_tran_version_store查看版本存储区的所有内容,但要注意。这个动态管理视图会消耗大量资源。

版本存储区开销:

行版本控制的开销为每行14个字段,其中包括一个事务序列号以及一个行标识符。如图所示:


XSN 用于串联同一行的多个版本6个字节,RID 用于定位tempdb中的行版本8个字节。

这个14个字节开销不会降低每行最多8060字节的限制。如果数据页满了,那么创建额外的14个字节可能会导致页面拆分,从而可能影响磁盘的空间需求。

只追存储区

行版本信息被写入两种只追加存储区;索引重建有自己的版本存储区,所有其他操作有一个公共的存储区。为了提高可扩展性,每个CPU调度器在版本存储区中都有自己的页面来存储行。

可能有人想到,不可能总是追加,没有删除吧。当然有,sqlserver后台有个一个专门的线程每分钟都从tempdb中删除陈旧的行版本。

  待续...