为什么在SQL中使用表值函数而不是临时表?

时间:2012-12-06 00:39:52

标签: sql stored-procedures stored-functions

我正在尝试加速我的存储过程的怪物,该存储过程可以在许多表中处理数百万条记录。

我偶然发现了这个: Is it possible to use a Stored Procedure as a subquery in SQL Server 2008?

我的问题是为什么使用表值函数比使用临时表更好。

假设我的存储过程@ SP1

declare @temp table(a int)


insert into @temp 
select a from BigTable 
where someRecords like 'blue%'

update AnotherBigTable
set someRecords = 'were blue'
from AnotherBigTable t 
inner join
@temp
on t.RecordID = @temp.a

在阅读上面的链接之后,似乎消费者不是将我的@temp用作临时表,而是创建一个表值函数来执行该选择。 (并且如果它是一个简单的选择,就像我在这个例子中那样内联它)但是我的实际选择是多个并且通常不简单(即有子网格等) 有什么好处?

由于

2 个答案:

答案 0 :(得分:3)

通常,您将使用临时表(#)而不是表变量。表变量实际上只对

有用
  • 函数,无法创建临时对象
  • 将表值数据(集)作为只读参数传递
  • 某些查询边缘情况的游戏统计信息
  • 执行计划稳定性(与统计相关,以及INSERT INTO表变量不能使用并行计划的事实)
  • 在SQL Server 2012之前,#temp表继承tempdb的排序规则,而@table变量使用当前的数据库排序规则

除了这些之外,#tempmporary表也可以比变量更好。

进一步阅读:What's the difference between a temp table and table variable in SQL Server?

答案 1 :(得分:0)

可能不再相关......但我可能建议采取两种不同的方法。

简单方法1:


在表值变量上尝试一个主键:

declare @temp table(a int, primary key(a))

简单方法2:

在这种特殊情况下,尝试使用公用表表达式(CTE)...

;with

   temp as ( 
      SELECT      a as Id
      FROM        BigTable
      WHERE       someRecords like '%blue'
   ),

 UPDATE    AnotherBigTable
 SET       someRecords = 'were Blue'
 FROM      AnotherBigTable
 JOIN      temp
   ON      temp.Id = AnotherBigTable.RecordId

CTE非常棒,有助于从大型表格中包含的无数记录中隔离您实际想要处理的特定数据集...如果您发现自己重复使用相同的CTE声明,请考虑将该表达式正式化为视图。对于DBA和DB程序员来说,视图是一个经常被忽视且非常有价值的工具,可以管理具有大量记录和关系的大型复杂数据集。