表变量存储在内存中,而临时表存储在tempdb中,会涉及到物理IO读写,那么我们是否可以由此得出结论,使用表变量要比使用临时表效率高呢?相信有一部分人会和我有同样的想法,使用表变量的效率高,真是如此吗?先从一次优化存储过程的经历说起。

存储过程涉及到两个表,一个是用户今日积分表@tableUserScore(数据源来自用户积分详情表中的今日数据),一个是用户积分统计表UserScoreSum,该存储过程逻辑就是统计@tableUserScore中用户不同原因的积分值,生成到表UserScoreSum中。数据量不算很大,@tableUserScore中大概40万条,但这个存储过程执行时间却有些惊人,通常都在1个小时之上。优化的最终结果是将表变量@tabeUserScore换成了临时表#tableUserScore,并在userid和reason上添加了联合索引,优化的效果是执行时间控制在了40S左右。临时表和表变量效率相差百倍,这次优化经历让我对临时表和表变量有了重新认识,也有了一连串的疑问,它们是如何存储的,效率如何,如何选用?

表结构

declare @tableUserScore table(
userid int, --用户编号
name varchar(10), --用户姓名
reason varchar(32), --积分原因
score int --积分值
)

create table UserScoreSum(
userid int, --用户编号
name varchar(10), --用户姓名
createTime datetime, --时间
reason1Score int, --原因1积分值
reason2Score int, --原因2积分值
reason3Score int, --原因3积分值
reason4Score int, --原因4积分值
)

以下是个人翻阅资料后的理解,总结出来希望能给和我有同样认识的人提个醒,起到抛砖引玉的作用,也希望大家对理解错误之处提出指正。

临时表

临时表有两种类型:本地表和全局表。在与首次创建或引用表时相同的 SQL Server 实例连接期间,本地临时表只对于创建者是可见的。当用户与 SQL Server 实例断开连接后,将删除本地临时表。全局临时表在创建后对任何用户和任何连接都是可见的,当引用该表的所有用户都与 SQL Server 实例断开连接后,将删除全局临时表。本地临时表的名称都是以“#”为前缀,全局临时表的名称都是以“##”为前缀。

临时表存储在tempdb中,因此临时表的访问是有可能造成物理IO的,当然在修改时也需要生成日志来确保一致性,同时锁机制也是不可缺少的。

临时表可以创建索引,也可以定义统计数据,所以可以用数据定义语言(DDL)的声明来阻止临时表添加的限制,约束,并参照完整性,如主键和外键约束。

     表变量

表变量是变量的一种,表变量也分为本地及全局的两种,本地表变量的名称都是以“@”为前缀,只有在本地当前的用户连接中才可以访问。全局的表变量的名称都是以“@@”为前缀,一般都是系统的全局变量,像我们常用到的,如@@Error代表错误的号,@@RowCount代表影响的行数。

表变量存放在内存中,正是因为这一点所有用户访问表变量的时候SQL Server是不需要生成日志。同时变量是不需要考虑其他会话访问的问题,因此也不需要锁机制,对于非常繁忙的系统来说,避免锁的使用可以减少一部分系统负载。[表变量存放在内存是有一定限制的,如果表变量数据量超过阈值,会把内存耗尽,然后使用TempDB的空间,这样主要还是使用硬盘空间,但同时把内存基本耗尽,增加了内存调入调出的机会,反而降低速度]

表变量另外还有一个限制就是不能创建索引,当然也不存在统计数据的问题,因此在用户访问表变量的时候也就不存在执行计划选择的问题了(也就是以为着编译阶段后就没有优化阶段了),这一特性有的时候是件好事,而有些时候却会造成一些麻烦。

临时表 vs. 表变量

1.存储位置:临时表是利用了硬盘(tempdb数据库) ,表名变量是占用内存,因此小数据量当然是内存中的表变量更快。当大数据量时,就不能用表变量了,太耗内存了。大数据量时适合用临时表。

2.性能:不能一概而论,表变量存储数据有个性能临界点,在这个临界点之内,表变量比临时表快,表变量是存储在内存中的。

3.索引:表变量不支持索引和统计数据,但可以有主键;临时表则可以支持索引和统计数据。

我们对于较小的临时计算用数据集考虑使用表变量。如果数据集比较大,如果在代码中用于临时计算,同时这种临时使用永远都是简单的全数据集扫描而不需要考虑什么优化,比如说没有分组或分组很少的聚合(比如说COUNT、SUM、AVERAGE、MAX等),也可以考虑使用表变量。使用表变量另外一个考虑因素是应用环境的内存压力,如果代码的运行实例很多,就要特别注意内存变量对内存的消耗。一般对于大的数据集我们最好使用临时表,同时创建索引。

转载于:https://www.cnblogs.com/RealmKing/p/4364766.html

表变量和临时表的使用相关推荐

  1. 【译】表变量和临时表的比较(转)

    关于表变量是什么(和表变量不是什么),以及和临时表的比较让很多人非常困惑.虽然网上已经有了很多关于它们的文章,但我并没有发现一篇比较全面的.在本篇文章中,我们将探索表变量和临时表是什么(以及不是什么) ...

  2. T-SQL 之 表变量和临时表

    一.表变量 表变量在SQL Server 2000中首次被引入.表变量的具体定义包括列定义,列名,数据类型和约束.而在表变量中可以使用的约束包括主键约束,唯一约束,NULL约束和CHECK约束(外键约 ...

  3. 表变量与临时表的优缺点?(ZT)

    什么情况下使用表变量?   什么情况下临时表?   ---------------------------------------------------------------     表变量只存放 ...

  4. SQL Server 表变量和临时表的区别

    一.表变量 表变量在SQL Server 2000中首次被引入.表变量的具体定义包括列定义,列名,数据类型和约束.而在表变量中可以使用的约束包括主键约束,唯一约束,NULL约束和CHECK约束(外键约 ...

  5. 【译】表变量和临时表的比较

    关于表变量是什么(和表变量不是什么),以及和临时表的比较让很多人非常困惑.虽然网上已经有了很多关于它们的文章,但我并没有发现一篇比较全面的.在本篇文章中,我们将探索表变量和临时表是什么(以及不是什么) ...

  6. 表变量与临时表的优缺点

    表变量与临时表的优缺点 什么情况下使用表变量?什么情况下使用临时表? 表变量: DECLARE @tb  table(id   int   identity(1,1), name   varchar( ...

  7. mysql表变量临时表_表变量和临时表详解

    首先让我们来看看什么是表变量和临时表. sql server 表变量 1.初识表变量 表变量在sql server 2000中首次被引用.表变量的定义和创建一个表大致相同,只不过是使用DECLARE ...

  8. SQL Server中临时表与表变量的区别

    我们在数据库中使用表的时候,经常会遇到两种使用表的方法,分别就是使用临时表及表变量.在实际使用的时候,我们如何灵活的在存储过程中运用它们,虽然它们实现的功能基本上是一样的,可如何在一个存储过程中有时候 ...

  9. [导入]SQL中的临时表和表变量

    我们经常使用临时表和表变量,那现在我们就对临时表和表变量进行一下讨论. 临时表 局部临时表 全局临时表 表变量 临时表 临 时表存储在TempDB数据库中,所有的使用此SQL Server 实例的用户 ...

最新文章

  1. java不是有效_单选(2分) 以下哪个不是有效的Java变量名?
  2. MEET2020 | 嘉宾已确认!李开复、倪光南等AI大咖齐聚,共话人工智能新价值新边界新格局...
  3. python做动态折线图_Python数据可视化 pyecharts实现各种统计图表过程详解
  4. memcached 扩展安装(windows)
  5. pythonfor循环100次_在for循环中只打印一次
  6. HDU - 1160 FatMouse's Speed(最长不下降子序列)
  7. Android之如何解决刚下载的Android studio(包括上面的菜单栏)乱码问题
  8. 安卓学习日记:初识Android Studio · java环境配置和AS安装
  9. 第11课 尼克与强盗 《小学生C++趣味编程》
  10. mysql大事务commit快_MYSQL事务他快你慢,都是你自己惹的祸
  11. jwt如何防止token被窃取_如何使用 NodeJS 实现 JWT 原理
  12. mac 查看本机ip地址命令
  13. IE故障修复之点击无反应
  14. Excel操作:分析工具库
  15. 微信小程序支付---详解(python)
  16. 图(3)——邻接链表法
  17. win10把AppData目录挪到其他盘的方法
  18. 统计一个字符串中单词的个数(C语言)
  19. 实现App跳转到应用商店
  20. PAT_乙级_1006_筱筱

热门文章

  1. Joi验证模块的使用
  2. Chapter7-12_Controllable Chatbot
  3. LeetCode 2138. 将字符串拆分为若干长度为 k 的组
  4. LeetCode 1870. 准时到达的列车最小时速(二分查找)
  5. LeetCode 734. 句子相似性(哈希)
  6. LeetCode 1353. 最多可以参加的会议数目(排序+贪心,优先队列,难)
  7. android model 设计,Android model层设计
  8. python股票历史最低点_Python统计某一只股票每天的开盘,收盘,最高,最低价格!...
  9. wltc循环多少公里_原来所有车都烧机油!但是烧多少才算正常你知道吗?
  10. php中写salt,请快速检查这个PHP+SALT实现-不工作?