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

Posted

技术标签:

【中文标题】为啥在 SQL 中使用表值函数而不是临时表?【英文标题】:Why use table valued function instead of a temp table in SQL?为什么在 SQL 中使用表值函数而不是临时表? 【发布时间】:2012-12-06 00:39:51 【问题描述】:

我正在尝试加快我的存储过程怪物的速度,该过程适用于许多表中的数百万条记录。

我偶然发现了这个: 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

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

谢谢

【问题讨论】:

【参考方案1】:

通常,您会使用临时表 (#) 来代替表变量。表变量真的只对

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

除此之外,#temporary 表的工作效果与变量一样好。

延伸阅读:What's the difference between a temp table and table variable in SQL Server?

【讨论】:

【参考方案2】:

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

简单方法一:


在表值变量上尝试主键:

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 程序员来说,视图是一个经常被忽视且非常有价值的工具,用于管理具有大量记录和关系的大型复杂数据集。

【讨论】:

以上是关于为啥在 SQL 中使用表值函数而不是临时表?的主要内容,如果未能解决你的问题,请参考以下文章

子查询 X 临时表 X 动态 sql X 表值函数

sql 表值函数-将一个传入的字符串用2中分隔符拆分成临时表

从表值函数返回表并在临时表中设置该值

在表值函数中使用临时表

表值参数

SQL Server存储过程中使用表值作为输入参数示例