我有一个存储过程,在其中创建了一个临时表,该表通常包含 1 到 10 行。该表在存储过程中被截断并填充了很多次。它被截断,因为这比删除更快。当我因使用删除而受到惩罚时(截断不适用于表变量),是否可以通过用表变量替换此临时表来提高性能?
虽然表变量主要在内存中并且通常比临时表快,但我是否会因为必须删除而不是截断而失去任何好处?
我有一个存储过程,在其中创建了一个临时表,该表通常包含 1 到 10 行。该表在存储过程中被截断并填充了很多次。它被截断,因为这比删除更快。当我因使用删除而受到惩罚时(截断不适用于表变量),是否可以通过用表变量替换此临时表来提高性能?
虽然表变量主要在内存中并且通常比临时表快,但我是否会因为必须删除而不是截断而失去任何好处?
对脚本运行以下命令,似乎表变量是更好的选择
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
坦率地说,只有 10 或 20 个(甚至 100 个)条目,速度上的任何差异都将在亚纳秒范围内。忘记它——甚至不要在这上面浪费你一秒钟的大脑时间——这不是问题!
一般来说
表变量将在内存中保留一定大小 - 如果超出此范围,它们也会被换出到tempdb
数据库中的磁盘 - 就像临时表一样。另外:如果一个临时表只有少数条目,它们最喜欢存储在一个 8k 页面上,一旦您访问其中一个条目,整个页面(以及整个临时表)将在 SQL Server 内存中 - 所以即使在这里,表变量也没有太多好处......
表变量不支持索引也不支持统计,这意味着如果你有多个条目,特别是如果你需要搜索和查询这个“实体”,你最好使用临时表
总而言之:我个人使用临时表比表变量更频繁,特别是如果我有超过 10 个条目或类似的东西。在性能方面,与表变量可能具有的任何潜在收益相比,能够索引临时表并对其进行统计通常会带来很大的回报。