在什么时候应该放弃表变量用于临时表?

时间:2010-05-27 13:29:06

标签: sql sql-server tsql

是否有行计数使表变量效率低或者是什么?我理解两者之间的差异,并且在达到这一点时我看到了一些不同的数字,但我很好奇是否有人知道。

2 个答案:

答案 0 :(得分:3)

当你需要表上的其他索引而不是可以在临时表变量上创建的索引时,或者对于较大的数据集(不太可能在可用内存中持久化),当表宽度(字节数)时每行)超过某个阈值(这是因为每个I / O页面的数据的数量或数量会缩小,性能会下降......或者您计划对数据集进行的更改是否需要成为多语句事务的一部分可能需要回滚。(对表变量的更改不会写入事务日志,对临时表的更改是......)

此代码演示了表变量未存储在事务日志中:

create table #T (s varchar(128)) 
declare @T table (s varchar(128)) 
insert into #T select 'old value #' 
insert into @T select 'old value @' 
begin transaction 
     update #T set s='new value #' 
     update @T set s='new value @' 
rollback transaction 
select * from #T 
select * from @T 

答案 1 :(得分:2)

在内部,表变量可以在tempdb以及临时表中实例化。

它们的范围和持久性不同。

与流行的看法相反,对临时表的操作会影响事务日志,尽管它们不受事务控制的约束。

要检查它,请运行以下简单查询:

DECLARE @mytable TABLE (id INT NOT NULL PRIMARY KEY)
;
WITH    q(num) AS
        (
        SELECT  1
        UNION ALL
        SELECT  num + 1
        FROM    q
        WHERE   num <= 42
        )
INSERT
INTO    @mytable (id)
SELECT  num
FROM    q
OPTION (MAXRECURSION 0)

DBCC LOG(tempdb, -1)
GO
DBCC LOG(tempdb, -1)
GO

并浏览两个记录集中的最后一个条目。

在第一个记录集中,您会看到42 LOP_INSERT_ROWS条目。

在第二个记录集(在另一个批次中),您将看到42 LOP_DELETE_ROWS条目。

它们是表变量超出范围并且其记录被删除的结果。