设为首页 收藏本站
查看: 682|回复: 0

[经验分享] 临时表和表变量区别,SQL Server里的视图和临时表在哪里?

[复制链接]

尚未签到

发表于 2015-7-4 14:57:04 | 显示全部楼层 |阅读模式
  临时表与永久表相似,但临时表存储在 tempdb 中,当不再使用时会自动删除。
  临时表有两种类型:本地和全局。它们在名称、可见性以及可用性上有区别。本地临时表的名称以单个数字符号 (#) 打头;它们仅对当前的用户连接是可见的;当用户从 SQL Server 实例断开连接时被删除。全局临时表的名称以两个数字符号 (##) 打头,创建后对任何用户都是可见的,当所有引用该表的用户从 SQL Server 断开连接时被删除。
  例如,如果创建了 employees 表,则任何在数据库中有使用该表的安全权限的用户都可以使用该表,除非已将其删除。如果数据库会话创建了本地临时表 #employees,则仅会话可以使用该表,会话断开连接后就将该表删除。如果创建了 ##employees 全局临时表,则数据库中的任何用户均可使用该表。如果该表在您创建后没有其他用户使用,则当您断开连接时该表删除。如果您创建该表后另一个用户在使用该 表,则 SQL Server 将在您断开连接并且所有其他会话不再使用该表时将其删除。
  临时表
  临时表存储在TempDB数据库中,所有的使用此SQL Server 实例的用户都共享这个TempDB,因为我们应该确保用来存储TempDB数据库的硬盘有足够的空间,以使之能够自己的增长.最好能够存储在一个拥有独立 硬盘控制器上.因为这样不存在和其它的硬盘I/O进行争用.   
  我们很多程序员认为临时表非常危险,因为临时表有可能被多个连接所共享.其实在SQL Server中存在两种临时表:局部临时表和全局临时表,局部临时表(Local temp table)以#前缀来标识,并且只能被创建它的连接所使用.全局临时表(Global temp table)以##前缀来进行标识,并且可以和其它连接所共享.
  局部临时表
  局部临时表不能够被其它连接所共享的原因其实是在SQL Server 2000中自动为局部临时表的表名后面加上了一个唯一字符来标识.如:
  CREATE TABLE [#DimCustomer_test]
  (
  [CustomerKey] [int]
  ,    [FirstName] [nvarchar](50)   
  ,[MiddleName] [nvarchar](50)   
  ,[LastName] [nvarchar](50)
  )
  现在我们来查看一下TempDB中 sysobjects表,我们会发现我们新创建的临时表#DimCustomer_test已经被加上了后缀:
  
  USE TempDB
  GO
  SELECT name FROM sysobjects WHERE name LIKE ’%DimCustomer%’
  
  the Result is:
  name
  #DimCustomer_test___________________________________________________________________________________________________000000000005
  全局临时表
  下面我们来看一下全局临时表:
  CREATE TABLE [##DimCustomer_test]
  (
  [CustomerKey] [int]
  ,       [FirstName] [nvarchar](50)   
  ,[MiddleName] [nvarchar](50)   
  ,[LastName] [nvarchar](50)
  )
  现在我们来查看一下TempDB中 sysobjects表,我们会发现我们新创建的临时表##DimCustomer_test没有被加上了后缀:
  
  USE TempDB
  GO
  SELECT name FROM sysobjects WHERE name LIKE ’%DimCustomer%’
  
  The Result are:
  #DimCustomer_test___________________________________________________________________________________________________000000000005
  ##DimCustomer_test
  
  --Drop test temp tables
  DROP TABLE [##DimCustomer_test]
  DROP TABLE [#DimCustomer_test]
  
  可以看到我们刚才创建的全局临时表名字并没有被加上标识.
  
  表变量
  表变量和临时表针对我们使用人员来说并没有什么不同,但是在存储方面来说,他们是不同的,表变量存储在内存中.所以在性能上和临时表相比会更好些!
  
  另一个不同的地方是在表连接中使用表变量时,要为此表变量指定别名.如:
  
  USE AdventureWorksDW
  GO
  
  DECLARE @DimCustomer_test TABLE
  (
  [CustomerKey] [int]
  ,       [FirstName] [nvarchar](50)   
  ,[MiddleName] [nvarchar](50)   
  ,[LastName] [nvarchar](50)
  )
  ---insert data to @DimCustomer_test
  INSERT @DimCustomer_test
  (
  [CustomerKey]   
  ,       [FirstName]   
  ,[MiddleName]   
  ,[LastName]
  )
  SELECT   
  [CustomerKey]   
  ,       [FirstName]   
  ,[MiddleName]   
  ,[LastName]
  FROM DimCustomer
  
  SELECT [@DimCustomer_test].CustomerKey,SUM(FactInternetSales.OrderQuantity)
  FROM @DimCustomer_test   INNER JOIN FactInternetSales    ON
  @DimCustomer_test.CustomerKey = FactInternetSales.CustomerKey
  Group BY CustomerKey
  
  Result:
  
  Server: Msg 137, Level 15, State 2, Line 32
  Must declare the variable ’@DimCustomer_test’.
  
  
  如果我们对上面的查询进行更改,对查询使用别名(并且找开IO):
  -----in the follow script,we used the table alias.
  
  DECLARE @DimCustomer_test TABLE
  (
  [CustomerKey] [int]
  ,       [FirstName] [nvarchar](50)   
  ,[MiddleName] [nvarchar](50)   
  ,[LastName] [nvarchar](50)
  )
  
  INSERT @DimCustomer_test
  (
  [CustomerKey]   
  ,       [FirstName]   
  ,[MiddleName]   
  ,[LastName]
  )
  SELECT   
  [CustomerKey]   
  ,       [FirstName]   
  ,[MiddleName]   
  ,[LastName]
  FROM DimCustomer
  
  SELECT t.CustomerKey,f.OrderQuantity
  FROM @DimCustomer_test t INNER JOIN FactInternetSales   f ON
  t.CustomerKey = f.CustomerKey
  where t.CustomerKey=13513
  
  表变量在批处理结束时自动被系统删除,所以你不必要像使用临时表表一样显示的对它进行删除.
表变量主要开销系统的内存,而临时表则使用tempdb。对于小数据量的中间数据存储,可以使用表变量,而当需要临时保存的数据量很庞大时,建议使用临时表。具体使用表变量还是临时表,可以根据系统的运行状况来调整。
  ====================================================
  例如,如果创建名为   employees   的表,则任何人只要在数据库中有使用该表的安全权限就可以使用该表,除非它已删除。如果创建名为   #employees   的本地临时表,只有您能对该表执行操作且在断开连接时该表删除。如果创建名为   ##employees   的全局临时表,数据表中的任何用户均可对该表执行操作。如果该表在您创建后没有其他用户使用,则当您断开连接时该表删除。如果该表在您创建后有其他用户使 用,则   SQL   Server在所有用户断开连接后删除该表。
  =====================================================
  非索引视图只是一个定义, 不存储数据, 查询的时候才从基础表拿数据
  索引视图会存储数据
  
  索引视图和临时表的数据都存储在硬盘
  其中索引视图的数据存储在视图所在的数据库文件中
  临时表的数据存储在tempdb这个数据库文件中
  
本文来自博商网(wwwBS.NET):http://wwwbs.net/blog/articleview.aspx?user=admin&artid=11633

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-83123-1-1.html 上篇帖子: Visual C#的SQL Server数据库连接编程 下篇帖子: SQL Server 2008 Ent & Dev Key
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表