我有一个存储过程,在其中我创建了一个临时表,通常包含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
DELETE
是更好的选择,而且与使用表变量相比,在使用#temp
表时你会得到同样的结果。这是一个非常特殊的情况,因为这10行数据都可以放在一页中。TRUNCATE
会从表中回收最后一页的空间,而DELETE
则不会。由于表非常小,因此记录被删除行所需的开销小于持续回收和重新分配表中单个页面带来的开销。但对于大型表格,情况则不同。 - Martin Smith