临时表和表变量之间的INSERT性能差异


12

我在SQL Server 2005中遇到以下问题:与使用临时表进行相同插入相比,尝试将一些行插入表变量中需要花费大量时间。

这是要插入到表变量中的代码

DECLARE @Data TABLE(...)
INSERT INTO @DATA( ... )
SELECT ..
FROM ...

这是要插入到临时表中的代码

CREATE #Data TABLE(...)
INSERT INTO #DATA( ... )
SELECT ..
FROM ...
DROP TABLE #Data

临时表没有任何键或索引,两个查询之间的选择部分相同,并且选择返回的结果数约为10000行。单独执行选择所需的时间约为10秒。

临时表版本最多需要10秒才能执行,我不得不在5分钟后停止表变量版本。

我必须使用表变量,因为查询是表值函数的一部分,该函数不允许访问临时表。

表变量版本的执行计划 执行计划

临时表版本的执行计划 执行计划

Answers:


8

两种方案之间的明显区别是,最快的方案是并行的,而较慢的方案是串行的。

这是插入表变量的计划的局限性之一。正如评论中所提到的(似乎已经达到了预期的效果),您可以尝试做

INSERT INTO @DATA ( ... ) 
EXEC('SELECT .. FROM ...')

看看是否能解决限制。


这是一个很好的建议,尽管我虽然不能EXEC在函数上使用....猜测我错了
Lamak

1
@Lamak-Doh!您不能这样做,这将不适用于OP。Invalid use of a side-effecting operator 'INSERT EXEC' within a function.OPENQUERY工作围绕可能的工作,虽然。
马丁·史密斯

嗯,好知道,感谢澄清
Lamak

2
作为一般经验法则,如果期望返回大量数据集,则不希望使用表变量。在这种情况下,临时表通常更快。
HLGEM 2012年

1
@munissor,然后不要使用表值函数。如果您想获得更好的建议,请确切地发布您的操作。
HLGEM 2012年

-1

由于没有关于表变量的统计信息,因此表变量有时会变慢,因此优化器始终仅假设一条记录。

但是,我不能保证在这里是这种情况,您将不得不查看表变量的查询计划中的“估计行数”信息。


这将如何影响对表变量的插入?
马丁·史密斯

这就是正在发生的情况,因为您可以看到并行和串行之间以及哈希和嵌套循环连接之间不仅存在差异,优化器显然认为,由于表变量在其脑海中保存着一条记录,因此结果的查询也将是一条记录,再次证明它的唯一方法是查看查询的每个部分的实际统计信息,但事实是,所有涉及表变量的查询都以循环联接和串行处理结尾,所以我想在这里怀疑它是很公平的
yoel halb 2013年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.