3

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

我偶然发现了这一点: 是否可以在 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 作为临时表,而是创建一个表值函数来执行该选择。(如果它像我在这个例子中那样简单选择,则将其内联)但是我的实际选择是多个并且通常不简单(即带有子查询等)有什么好处?

谢谢

4

2 回答 2

3

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

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

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

进一步阅读:SQL Server 中的临时表和表变量有什么区别?

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

于 2014-02-11T23:03:28.300 回答