区别一:
Table变量和临时表区别<PRE lang=sql>CREATE table #T (s varchar(128))
Table变量和临时表区别
DECLARE @T table (s varchar(128))
Table变量和临时表区别
INSERT into #T select 'old value #'
Table变量和临时表区别
INSERT into @T select 'old value @'
Table变量和临时表区别
BEGIN transaction
Table变量和临时表区别  
UPDATE #T set s='new value #'
Table变量和临时表区别  
UPDATE @T set s='new value @'
Table变量和临时表区别
ROLLBACK transaction
Table变量和临时表区别
SELECT * from #T
Table变量和临时表区别
SELECT * from @T
Table变量和临时表区别s             
Table变量和临时表区别
---------------
Table变量和临时表区别
old value #
Table变量和临时表区别
Table变量和临时表区别s                
Table变量和临时表区别
---------------
Table变量和临时表区别
new value @</PRE>
这行代码一目了然,临时表能起到事务回滚的作用,但是table变量不可以.作者解释是table变量不在事务作用范围之内.所以当table变量即使遇到回滚命令,但是也不会真的执行回滚.

区别二:
任何含有临时表的存储过程是不能被预编译的.这在一个很长的存储过程中,优势会更加凸显.

区别三:
table变量作为变量只能在同范围内存在,不可能跨范围.还有就是table变量在内置的存储过程中或者exec(string)语句中是不可见的还有就是不能被用于INSERT/EXEC statements.

下面的例子我来演示如何对比临时表和table变量在存储过程中预编译的区别.
创建一个测试表:
Table变量和临时表区别CREATE table NUM (n int primary key, s varchar(128))
Table变量和临时表区别
GO
Table变量和临时表区别
SET nocount on
Table变量和临时表区别
DECLARE @n int
Table变量和临时表区别
SET @n=1000000
Table变量和临时表区别
WHILE @n>0 begin
Table变量和临时表区别  
INSERT into NUM
Table变量和临时表区别    
SELECT @n,'Value: '+convert(varchar,@n)
Table变量和临时表区别  
SET @n=@n-1
Table变量和临时表区别  
END
Table变量和临时表区别
GO

然后创建存储过程:T1
Table变量和临时表区别CREATE procedure T1
Table变量和临时表区别  
@total int
Table变量和临时表区别
AS
Table变量和临时表区别  
CREATE table #T (n int, s varchar(128))
Table变量和临时表区别  
INSERT into #T select n,s from NUM
Table变量和临时表区别    
WHERE n%100>0 and n<=@total
Table变量和临时表区别  
DECLARE @res varchar(128)
Table变量和临时表区别  
SELECT @res=max(s) from NUM
Table变量和临时表区别    
WHERE n<=@total and
Table变量和临时表区别      
NOT exists(select * from #T
Table变量和临时表区别      
WHERE #T.n=NUM.n)
Table变量和临时表区别
GO
这个存储过程的参数@Total给定的越大,那么执行的时间越长.


为精确测量存储过程执行时间,我使用了以下代码:
Table变量和临时表区别DECLARE @t1 datetime@n int
Table变量和临时表区别
SET @t1=getdate()
Table变量和临时表区别
SET @n=100 – (**)
Table变量和临时表区别
WHILE @n>0 begin
Table变量和临时表区别  
EXEC T1 1000 – (*)
Table变量和临时表区别  
SET @n=@n-1 end
Table变量和临时表区别
SELECT datediff(ms,@t1,getdate())
Table变量和临时表区别
GO
(*) 是存储过程参数.

现在我们给这个存储过程来第一次提速:个它加个主键
Table变量和临时表区别CREATE procedure T2
Table变量和临时表区别  
@total int
Table变量和临时表区别
AS
Table变量和临时表区别  
CREATE table #T (n int primary key, s varchar(128))
Table变量和临时表区别  
INSERT into #T select n,s from NUM
Table变量和临时表区别    
WHERE n%100>0 and n<=@total
Table变量和临时表区别  
DECLARE @res varchar(128)
Table变量和临时表区别  
SELECT @res=max(s) from NUM
Table变量和临时表区别    
WHERE n<=@total and
Table变量和临时表区别      
NOT exists(select * from #T
Table变量和临时表区别      
WHERE #T.n=NUM.n)
Table变量和临时表区别
GO
在下面的对比中你可以发现已经大大的提速了.

然后再来一次提速:给它加个聚集索引
Table变量和临时表区别CREATE procedure T3
Table变量和临时表区别  
@total int
Table变量和临时表区别
AS
Table变量和临时表区别  
CREATE table #T (n int, s varchar(128))
Table变量和临时表区别  
INSERT into #T select n,s from NUM
Table变量和临时表区别    
WHERE n%100>0 and n<=@total
Table变量和临时表区别  
CREATE clustered index Tind on #T (n)
Table变量和临时表区别  
DECLARE @res varchar(128)
Table变量和临时表区别  
SELECT @res=max(s) from NUM
Table变量和临时表区别    
WHERE n<=@total and
Table变量和临时表区别      
NOT exists(select * from #T
Table变量和临时表区别      
WHERE #T.n=NUM.n)
Table变量和临时表区别
GO

很惊讶速度已经提高了很多!

那好了,咱们再来测试一下table变量的速度吧
Table变量和临时表区别CREARE procedure V1
Table变量和临时表区别  
@total int
Table变量和临时表区别
AS
Table变量和临时表区别  
DECLARE @V table (n int, s varchar(128))
Table变量和临时表区别  
INSERT into @V select n,s from NUM
Table变量和临时表区别    
WHERE n%100>0 and n<=@total
Table变量和临时表区别  
DECLARE @res varchar(128)
Table变量和临时表区别  
SELECT @res=max(s) from NUM
Table变量和临时表区别    
WHERE n<=@total and
Table变量和临时表区别      
NOT exists(select * from @V V
Table变量和临时表区别      
WHERE V.n=NUM.n)
Table变量和临时表区别
GO

然后再来创建一个有主键的:
Table变量和临时表区别CREATE procedure V2
Table变量和临时表区别  
@total int
Table变量和临时表区别
AS
Table变量和临时表区别  
DECLARE @V table (n int primary key, s varchar(128))
Table变量和临时表区别  
INSERT into @V select n,s from NUM
Table变量和临时表区别    
WHERE n%100>0 and n<=@total
Table变量和临时表区别  
DECLARE @res varchar(128)
Table变量和临时表区别  
SELECT @res=max(s) from NUM
Table变量和临时表区别    
WHERE n<=@total and
Table变量和临时表区别      
NOT exists(select * from @V V
Table变量和临时表区别      WHEREre V.n
=NUM.n)
Table变量和临时表区别
GO<

然后咱们来看看我测试的结果吧!
Table 1, using SQL Server 2000, time in ms

Records
T1 T2 T3 V1 V2
10 0.7 1 13.5 0.6 0.8
100 1.2 1.7 14.2 1.2 1.3
1000 7.1 5.5 27 7 5.3
10000 72 57 82 71 48
100000 883 480 580 840 510
1000000 45056 6090 15220 20240 12010


But the real shock is when you try the same on SQL Server 2005:

Table 2

N
T1 T2 T3 V1 V2
10 0.5 0.5 5.3 0.2 0.2
100 2 1.2 6.4 61.8 2.5
1000 9.3 8.5 13.5 168 140
10000 67.4 79.2 71.3 17133 13910
100000 700 794 659

Too long!

Too long!

1000000 10556 8673 6440

Too long!

Too long!


发现对比在某些情况下sql2000的速度要比2005的要快上很多!


结论:
没有通用的规则指导你什么时候用临时表什么时候用table变量.
将复杂逻辑的存储过程移植到sql2005的时候,要格外小心!他可能比2000的效率要慢上好几十倍的!
在你的实际测试中,请测试两个极端:销量数据和超大量数据.

此文章翻译自codeproject:http://www.codeproject.com/cs/database/SQP_performance.asp

相关文章: