SQL的表变量、全局临时表、局部临时表的使用

SQL中

全局变量以@@开头,局部变量以@开头,表变量的规则与变量是一样的。
全局临时表以##开头,局部临时表以#开头,临时表并不存储在当前用户数据库中,而是存在系统数据库tempdb中。
局部临时表是只有创建局部临时表的连接才能看的到的临时表,当该连接断开时,SQL Server会自动去除局部临时表
全局临时表在所有连接上都能看到,当创建全局临时表的连接断开后,SQL Server会自动出去全局临时表
有一种不需要定义的创建临时表的语句,直接将查询结果放进临时表中

1、局部临时表

SELECT ROW_NUMBER() OVER( ORDER BY name ) as rowunm 
    ,name as ctablename 

into [#temptable1]

FROM sysobjects 
WHERE xtype = 'U' 
order by name 

2、全局临时表

SELECT ROW_NUMBER() OVER( ORDER BY name ) as rowunm 
    ,name as ctablename 

into [##temptable2]

FROM sysobjects 
WHERE xtype = 'U' 
order by name 

3、直接写上临时数据库名生成临时表,临时表要下次重启数据库时才被清除,或者要自行删除表。

SELECT ROW_NUMBER() OVER( ORDER BY name ) as rowunm 
    ,name as ctablename 

into tempdb..temptable

FROM sysobjects 
WHERE xtype = 'U' 
order by name 

4、使用表变量

DECLARE @tb  table(rowunm   int   , ctablename   varchar(500))  
  
  INSERT @tb  
  SELECT ROW_NUMBER() OVER( ORDER BY name ) as rowunm 
    ,name as ctablename 
 FROM sysobjects 
  WHERE xtype = 'U' 
      order by name 

select * from  @tb

表变量和临时表的比较:

临时表是利用了硬盘(tempdb数据库) ,表名变量是占用内存,因此小数据量当然是内存中的表变量更快。当大数据量时,就不能用表变量了,太耗内存了。大数据量时适合用临时表。
表变量缺省放在内存,速度快,所以在触发器,存储过程里如果数据量不大,应该用表变量。
临时表缺省使用硬盘,一般来说速度比较慢,那是不是就不用临时表呢?也不是,在数据量比较大的时候,如果使用表变量,会把内存耗尽,然后使用 TEMPDB的空间,这样主要还是使用硬盘空间,但同时把内存基本耗尽,增加了内存调入调出的机会,反而降低速度。这种情况建议先给TEMPDB一次分配合适的空间,然后使用临时表。
临时表相对而言表变量主要是多了I/O时间,但少了对内存资源的占用。数据量较大的时候,由于对内存资源的消耗较少,使用临时表比表变量有更好的性能。
建议:触发器、自定义函数用表变量;存储过程看情况,大部分用表变量;特殊的应用,大数据量的场合用临时表。
表变量有明确的作用域,在定义表变量的函数、存储过程或批处理结束时,会自动清除表变量。
在存储过程中使用表变量与使用临时表相比,减少了存储过程的重新编译量。
涉及表变量的事务只在表变量更新期间存在。这样就减少了表变量对锁定和记录资源的需求。
表变量需要事先知道表结构,普通临时表,只在当前会话中可用与表变量相同into一下就可以了,方便;全局临时表:可在多个会话中使用存在于temp中需显示的drop。(不知道表结构情况下临时表方便一些)
全局临时表的功能是表变量没法达到的。
表变量不必删除,也就不会有命名冲突,临时表特别是全局临时表用的时候必须解决命名冲突。
应避免频繁创建和删除临时表,减少系统表资源的消耗。
在新建临时表时,如果一次性插入数据量很大,那么可以使用select into代替create table,避免log,提高速度;如果数据量不大,为了缓和系统表的资源,建议先create table,然后insert。
如果临时表的数据量较大,需要建立索引,那么应该将创建临时表和建立索引的过程放在单独一个子存储过程中,这样才能保证系统能够很好的使用到该临时表的索引。
如果使用到了临时表,在存储过程的最后务必将所有的临时表显式删除,先truncate table,然后drop table,这样可以避免系统表的较长时间锁定。
慎用大的临时表与其他大表的连接查询和修改,减低系统表负担,因为这种操作会在一条语句中多次使用tempdb的系统表。

你可能感兴趣的:(SQL)