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

测试方式:

分别对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

存储过程重新编译

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

照例是妹子镇贴:

最新文章

  1. 一些值得练习的github项目
  2. java移位运算符
  3. java基础知识回顾之javaIO类总结
  4. windows渗透被人忽视的一些小命令
  5. 1012 最小公倍数LCM
  6. python访问mysql将返回的表转化为json
  7. java中从1000万个随机数中查找出相同的10万个随机数花的最少时间
  8. C# winform 选择项 省市连动
  9. 简单概述 .NET Framework 各版本区别
  10. CXF之webservice
  11. SQL事务机制
  12. Android的图片,字符串,demin,color,以及Array,boolean,Integer资源的使用-android学习之旅(五十四)
  13. C#枚举的简单使用
  14. SpringBoot系列——Spring-Data-JPA(究极进化版) 自动生成单表基础增、删、改、查接口
  15. CentOS7.3安装Go运行和开发环境
  16. 修复android 5.0 Xutils的框架问题retry error, curr request is null
  17. MyEclipse部署WebLogic
  18. 复刻smartbits的国产网络测试工具minismb-如何测试协议限速
  19. html5 &amp; input &amp; accept attribute
  20. CentOS 7下KVM支持虚拟化/嵌套虚拟化配置

热门文章

  1. 使用maven将项目热发布到tomcat7的坑
  2. python进程之间修改数据[Manager]与进程池[Pool]
  3. php使用数组语法访问对象
  4. StringUtils学习
  5. DataTable的序列化和反序列化
  6. Django之常用命令以及问题汇总
  7. pthread_exit pthread_join
  8. SQL思维导图
  9. ShowMsg函数
  10. [Selenium]当DOM结构里面有iFrame,iFrame里面是html,怎么send keys to 里面的body,怎么用Assert进行验证?