在思考表变量与临时表之间区别时,表变量不会受事务回滚的影响,那么是否意味着表变量无需写入日志呢?

测试方式:

分别对tempdb上的用户表/临时表/表变量 进行10000次插入,查看日志写入次数,使用SYS.dm_io_virtual_file_stats可以查看数据库文件的读入和写入次数,也可以使用process monitor来捕获在tempdb的日志文件上的操作

1. 测试用户表

--=================================================
--测试tempdb上的表
USE tempdb
GO
CREATE TABLE TB1
(
ID INT
)
GO
SELECT * FROM SYS.dm_io_virtual_file_stats(2,1)
SELECT * FROM SYS.dm_io_virtual_file_stats(2,2) DECLARE @ID INT
SET @ID=0
WHILE(@ID<10000)
BEGIN
INSERT INTO TB1
SELECT @ID
SET @ID=@ID+1
END
SELECT * FROM SYS.dm_io_virtual_file_stats(2,1)
SELECT * FROM SYS.dm_io_virtual_file_stats(2,2)

2. 测试表变量

SELECT * FROM SYS.dm_io_virtual_file_stats(2,1)
SELECT * FROM SYS.dm_io_virtual_file_stats(2,2)
DECLARE @TB1 TABLE
(
ID INT
)
DECLARE @ID INT
SET @ID=0
WHILE(@ID<10000)
BEGIN
INSERT INTO @TB1
SELECT @ID
SET @ID=@ID+1
END SELECT * FROM SYS.dm_io_virtual_file_stats(2,1)
SELECT * FROM SYS.dm_io_virtual_file_stats(2,2)

3.测试临时表

SELECT * FROM SYS.dm_io_virtual_file_stats(2,1)
SELECT * FROM SYS.dm_io_virtual_file_stats(2,2)
CREATE TABLE #TB1
(
ID INT
)
DECLARE @ID INT
SET @ID=0
WHILE(@ID<10000)
BEGIN
INSERT INTO #TB1
SELECT @ID
SET @ID=@ID+1
END SELECT * FROM SYS.dm_io_virtual_file_stats(2,1)
SELECT * FROM SYS.dm_io_virtual_file_stats(2,2)

部分截图:

测试结果:

对边两次SYS.dm_io_virtual_file_stats的结果,可以发现日志上发生41次写操作,而process monitor也验证了41次写操作,每次写操作写入61kb数据(再次证明每次日志最大写入量)

无论是tempdb上的用户表还是表标量以及临时表,相同的操作所引发的日志写入次数是一样的,写入的总日志大小也大致相同。

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

在MS网站上找到如下:

涉及表变量的事务仅维持表变量上更新的持续时间。因此,使用表变量时,需要锁定和记录资源的情况更少。因为表变量具有有限的范围并且不是持久性数据库的一部分,所以事务回滚并不影响它们。

原文地址:http://support.microsoft.com/kb/305977/zh-cn

强烈推荐各位读一读这一篇

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

查看操作临时表的日志:

(注:表变量在tempdb中以临时表的方式出现)

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

个人猜想1:

既然MS把表变量的操作也记录在日志中,那么肯定有其保存的原因,在上面的测试过程中,表变量单独运行,但在很多事务中,表变量会参与其他用户对象的修改操作(如关联更新),因此需要将其变化记录到日志中,以便后续使用。

个人猜想2:

MS在SQL SERVER底层的一些操作上,把表变量和临时表当成同一类型来处理,因此调用了和临时表相同的方法来处理表变量,因此导致表变量也写入日志。

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

关于tempdb上的redo和undo

由于tempdb在每次实例重启后重新创建,不需要对tempdb上的数据做持久化处理,也不会发生redo操作,因此在记录日志时,不需要记录after image,只记录before image用于事务回滚操作。

PS:在tempdb上不会每次commit都触发写日志操作(本文上述测试中执行10000次事务,但只发生了41次写)。

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

相关链接:

Understanding data vs log usage for spills in tempdb

Working with tempdb in SQL Server 2005

存储过程重新编译

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

照例是妹子镇贴:

Tempdb--关于表变量的一点疑问和测试的更多相关文章

  1. SQLServer表变量对IO及内存影响测试

    原文:SQLServer表变量对IO及内存影响测试 1. 测试创建表变量对IO的影响 测试创建表变量前后,tempdb的空间大小,目前使用sp_spaceused得到大小,也可以使用视图sys.dm_ ...

  2. c#Winform程序调用app.config文件配置数据库连接字符串 SQL Server文章目录 浅谈SQL Server中统计对于查询的影响 有关索引的DMV SQL Server中的执行引擎入门 【译】表变量和临时表的比较 对于表列数据类型选择的一点思考 SQL Server复制入门(一)----复制简介 操作系统中的进程与线程

    c#Winform程序调用app.config文件配置数据库连接字符串 你新建winform项目的时候,会有一个app.config的配置文件,写在里面的<connectionStrings n ...

  3. (转)create table #temptable 临时表 和 declare @bianliang table ()表变量

    在开发过程中,经常会遇到使用表变量和本地临时表的情况.下面是对二者的一个介绍: 1. 为什么要使用表变量 表变量是从2000开始引入的,微软认为与本地临时表相比,表变量具有如下优点:  a.与其他变量 ...

  4. SqlServer 临时表 与 表变量(转)

    1. 表变量 变量都以@或@@为前缀,表变量是变量的一种,另外一种变量被称为标量(可以理解为标准变量,就是标准数据类型的变量,例如整型int或者日期型DateTime).以@前缀的表变量是本地的,因此 ...

  5. SQL Server 临时表 Vs 表变量

    开始 说临时表和表变量,这是一个古老的话题,我们在网上也找到很多的资料阐述两者的特征,优点与缺点.这里我们在SQL Server 2005\SQL Server 2008版本上通过举例子,说明临时表和 ...

  6. 【T-SQL系列】临时表、表变量

    临时表临时表与永久表相似,只是它的创建是在Tempdb中,它只有在一个数据库连接结束后或者由SQL命令DROP掉,才会消失,否则就会一直存在.临时表在创建的时候都会产生SQL Server的系统日志, ...

  7. SQL Server中的临时表和表变量 Declare @Tablename Table

    在SQL Server的性能调优中,有一个不可比面的问题:那就是如何在一段需要长时间的代码或被频繁调用的代码中处理临时数据集?表变量和临时表是两种选择.记得在给一家国内首屈一指的海运公司作SQL Se ...

  8. SQL Server中的临时表和表变量

    SQL Server中的临时表和表变量 作者:DrillChina出处:blog2008-07-08 10:05 在SQL Server的性能调优中,有一个不可比拟的问题:那就是如何在一段需要长时间的 ...

  9. sql:临时表和表变量

    在SQL Server的性能调优中,有一个不可比拟的问题:那就是如何在一段需要长时间的代码或被频繁调用的代码中处理临时数据集,表变量和临时表是两种选择. 临时表: 临时对象都以#或##为前缀,临时表是 ...

随机推荐

  1. kwic--Java统计单词个数并按照顺序输出

    2016-07-02(随笔写作时间) 写了好久的程序了为了避免以后用到.......... 是一个统计单词个数,并按照个数从大到小输出的.输入文件名OK 了 单词是按照首字母排序的,,,里面用到映射等 ...

  2. 利用python实现二分法和斐波那契序列

    利用python实现二分法:我的实现思路如下 1.判断要查找的值是否大于最大值,如果大于则直接返回False 2.判断要查找的值是否小于最小值,如果小于则直接返回False 3.如果要查找的值在最大值 ...

  3. 对ubuntu初学感想

    感觉对ubuntu一头雾水...作为什么都不懂得小菜鸟,感觉以后还有很多要学习的.fighting

  4. 启动apache时,出现httpd: Could not reliably determine the server\'s fully qualified domain name, using 127.0.0.1 for ServerName

    1.通过vi打开apache的配置文件httpd.conf > vi /data/apache/conf/httpd.conf 2.找到#ServerName www.example.com:8 ...

  5. Castle ActiveRecord学习(二)配置、引用、程序启动

    来源:http://www.cnblogs.com/zxj159/p/4082987.html 配置数据库驱动: Model层引用:Castle.ActiveRecord.dll.NHibernate ...

  6. socket编程介绍

    Python 提供了两个基本的 socket 模块. 第一个是 Socket,它提供了标准的 BSD Sockets API. 第二个是 SocketServer, 它提供了服务器中心类,可以简化网络 ...

  7. DB2中的数据类型

    DB2中的数据类型DB2内置数据类型可以分成数值型(numeric).字符串型(character string).图形字符串(graphic string).二进制字符串型(binary strin ...

  8. linux bluez

    Linux下开放的蓝牙协议栈主要包括IBM公司的BlueDrekar,Nokia公司的Affix, Axis公司的OpenBT和官方协议栈BlueZ.我们主要对Bluez进行探讨. BlueZ基础代码 ...

  9. boost 学习(1)

    智能指针的学习 中文教程网站 http://zh.highscore.de/cpp/boost/ 不过代码可能 由于BOOST 版本不同需要稍作修改 scoped_ptr 离开作用域则自动调用类析构函 ...

  10. java jvm入门 jvm什么意思 jvm调优

    接下来我会给大家讲解 国内最顶尖的jvm技术 不服来战