7

我有一个存储过程,在其中创建了一个临时表,该表通常包含 1 到 10 行。该表在存储过程中被截断并填充了很多次。它被截断,因为这比删除更快。当我因使用删除而受到惩罚时(截断不适用于表变量),是否可以通过用表变量替换此临时表来提高性能?

虽然表变量主要在内存中并且通常比临时表快,但我是否会因为必须删除而不是截断而失去任何好处?

4

2 回答 2

14

对脚本运行以下命令,似乎表变量是更好的选择

CREATE TABLE #Temp(
        ID INT
)

DECLARE @Int INT,
        @InnerInt INT
SELECT  @Int = 1,
        @InnerInt = 1

WHILE @Int < 50000
BEGIN
    WHILE @InnerInt < 10
    BEGIN
        INSERT INTO #Temp SELECT @InnerInt
        SET @InnerInt = @InnerInt + 1
    END
    SELECT @Int = @Int + 1,
            @InnerInt = 1
    TRUNCATE TABLE #Temp
END

DROP TABLE #TEMP

GO

DECLARE @Temp TABLE(
        ID INT
)

DECLARE @Int INT,
        @InnerInt INT
SELECT  @Int = 1,
        @InnerInt = 1

WHILE @Int < 50000
BEGIN
    WHILE @InnerInt < 10
    BEGIN
        INSERT INTO @Temp SELECT @InnerInt
        SET @InnerInt = @InnerInt + 1
    END
    SELECT @Int = @Int + 1,
            @InnerInt = 1
    DELETE FROM @Temp
END

来自 Sql Profiler

CPU     Reads   Writes  Duration
36375     2799937   0       39319

vs

CPU     Reads   Writes  Duration
14750   1700031 2       17376   
于 2010-04-15T15:41:44.220 回答
9

坦率地说,只有 10 或 20 个(甚至 100 个)条目,速度上的任何差异都将在亚纳秒范围内。忘记它——甚至不要在这上面浪费你一秒钟的大脑时间——这不是问题!

一般来说

  • 表变量将在内存中保留一定大小 - 如果超出此范围,它们也会被换出到tempdb数据库中的磁盘 - 就像临时表一样。另外:如果一个临时表只有少数条目,它们最喜欢存储在一个 8k 页面上,一旦您访问其中一个条目,整个页面(以及整个临时表)将在 SQL Server 内存中 - 所以即使在这里,表变量也没有太多好处......

  • 表变量不支持索引也不支持统计,这意味着如果你有多个条目,特别是如果你需要搜索和查询这个“实体”,你最好使用临时表

总而言之:我个人使用临时表比表变量更频繁,特别是如果我有超过 10 个条目或类似的东西。在性能方面,与表变量可能具有的任何潜在收益相比,能够索引临时表并对其进行统计通常会带来很大的回报。

于 2010-04-15T16:31:01.133 回答