我有几年前编写的某个存储过程。它使用表变量。在代码内部:
declare @OpportunityVS3 as SF_OpportunityMerge
insert @TableVariable select * from /*...*/
这是一个每五分钟运行一次的工作。过去曾经没有任何问题,因为select
过去常常收集大约10到1000条记录......但现在有时候,select会尝试插入一百万条记录。
鉴于此问题,我认为我被迫将@TableVariable
更改为#TempTable
。你怎么看?我还有其他选择吗?
在SP结束时,它将变量传递给另一个SP:
exec [dbo].[SF_MergeOpportunity] @OpportunityVS3, @LastUpdateDate
我想我必须在同一个存储过程中编写它,因为临时表不能传递,对吧?
以下是正在使用的@TableVariable
的定义以及我必须更改的代码:
declare @OpportunityVS3 as SF_OpportunityMerge
insert @OpportunityVS3 select Opportunity_id, Salesforce_id, AccountId, Age__c,
-- (continues)
merge [BU2].[dbo].[Salesforce_Opportunity] as TARGET
using ( select Opportunity_id,
Salesforce_id,
AccountId,
Age__c,
Amount,
Bill99Amount__c,
BJ_Marketing__c
-- (continues)
from @OpportunityVS3 ) as SOURCE on (TARGET.Opportunity_id = SOURCE.Opportunity_id)
exec [dbo].[SF_MergeOpportunity] @OpportunityVS3, @LastUpdateDate
[![在此处输入图像说明] [1]] [1]
[![在此处输入图像说明] [2]] [2]
答案 0 :(得分:0)
您可以尝试不改变工作方式:
TABLE
变量OPTION(RECOMPILE)
,强制编译器将TABLE
变量的基数考虑在内
UNIQUE INDEX
变量PRIMARY KEY
或TABLE
TABLE
变量的缺点是没有与它们相关的统计数据。当SQL编译器可以将统计信息考虑在内时,它将产生更好的执行计划。因此,当您切换到临时表时,可以显着提高性能,因为这些执行具有统计信息。
当您切换到临时表时,您将不再再将TABLE
变量传递给存储过程。然后,您的存储过程将使用它事先知道存在的临时表写入 - 即在执行存储过程之前创建。
您可以编写存储过程,就像临时表是普通表一样。当您使用临时表编写存储过程时,SQL Server管理工作室将以红色突出显示某些部分,因此看起来存储过程中存在错误。但是如果语法正确,创建/修改存储过程就可以了。
关于TABLE
变量和临时表之间的差异,请阅读此excellent essay,了解使用情况如何影响性能。特别是主题无列统计和索引。