性能/空间sql:选择@variable或#temp

时间:2015-09-23 13:05:55

标签: sql sql-server sql-server-2008 tsql sql-server-2012

我的存储过程给了我这个错误:

  

无法为对象和dbo.Large对象存储系统分配空间   对象:422213818384384'在数据库' tempdb'因为' PRIMARY'   文件组已满。 "

在我的查询中,我使用了很多临时表。我在想:

什么是更好的性能/空间?使用临时表或表变量与SELECT INTO之间有区别吗?

一个例子:

select * 
into #temp1 from myTable

select * 
into #temp2 from #temp1

--then add some columns on temp2 and do some joins with temp1

SELECTJOIN同样@temp1 / @temp2会更好吗?

2 个答案:

答案 0 :(得分:1)

正如其他人所说,在空间和表现方面,确实没有区别。有一种误解,表变量存储在RAM中,这是不正确的。两者都在tempdb空间中分配。

您的错误消息表明tempdb使用的文件已用完已分配的空间,这可能需要解决,耗尽tempdb空间可能是一个严重的问题。

一般的经验法则是首先避免创建不必要的对象(即临时表/临时数据集),让SQL Server尽最大努力以最简单的方式优化查询。

如果您创建了两个临时表,但没有看到数据/查询,则会产生两倍的数据,因此可能会使您的问题更加恶化。

根据您发布的内容,您应该避免使用临时表/表变量,而应使用普通查询。您可以使用子查询或公用表表达式来控制查询的复杂性。

答案 1 :(得分:0)

是的,Table变量和Temporary表虽然都使用TempDb,但它们不同。

选择表变量和临时表的基本拇指规则是,在处理较少量的数据时应选择表变量。表变量不涉及事务,锁定和日志记录,因此它们相对更快(usually good for less than 100 rows

除此之外,临时表允许您在其上有索引,它们就像临时数据库(TempDb)上存在的普通表一样。不要创建太多临时表,因为TempDb除了处理之外还必须执行各种其他操作用户定义的临时对象。因此,在您的情况下,您可以选择具有适当索引的物理表。我相信,你正在处理大量的blob对象,在这两种情况下(即表变量和临时表)都使用TempDb。