我在 SQLServer 2008 中创建了一个sql函数,该函数声明了一个临时表,并使用它来计算内部值的移动平均值
declare @tempTable table ( GeogType nvarchar(5), GeogValue nvarchar(7), dtAdmission date, timeInterval int, fromTime nvarchar(5), toTime nvarchar(5), EDSyndromeID tinyint, nVisits int ) insert @tempTable select * from aces.dbo.fEDVisitCounts(@geogType, @hospID,DATEADD(DD,-@windowDays + 1,@fromDate), @toDate,@minAge,@maxAge,@gender,@nIntervalsPerDay, @nSyndromeID) INSERT @table (dtAdmission,EDSyndromeID, MovingAvg) SELECT list.dtadmission , @nSyndromeID , AVG(data.nVisits) as MovingAvg from @tempTable as list inner join @tempTable as data ON list.dtAdmission between data.dtAdmission and DATEADD(DD,@windowDays - 1,data.dtAdmission) where list.dtAdmission >= @fromDate GROUP BY list.dtAdmission
但我还发现,您可以像这样声明tempTable:
with tempTable as ( select * from aces.dbo.fEDVisitCounts('ALL', null,DATEADD(DD,-7,'01-09-2010'), '04-09-2010',0,130,null,1, 0) )
问题:这两种方法是否有重大区别? 一个比另一个或更通用/标准快吗?我认为声明速度更快,因为您定义了要查找的列。如果我省略移动平均值计算中未使用的列,它还会更快吗?(不确定这一行)因为无论如何都要获得所有行,尽管选择较少的列在直觉上就意味着它会更快/更少地执行)
我还create temporary table @table从这里找到了一个如何在MySQL中声明内部表?但我不希望该表保留在函数之外(我不确定创建临时表是否执行此操作。)
create temporary table @table
该@table语法创建一个表变量(中的实际表tempdb),并将结果具体化为该变量。
@table
tempdb
该WITH语法定义了一个公共表表达式,该表未实现,只是一个内联视图。
WITH
在大多数情况下,使用第二个选项会更好。您提到这在函数内部。如果这是TVF,那么大多数时候您希望它们是内联而不是multi语句,以便可以通过优化程序将其扩展- 这将立即禁止使用表变量。
但是有时(例如,基础查询很昂贵,并且您希望避免多次执行该查询),您可能会确定在某些特定情况下,实现中间结果可以提高性能。有目前还没有办法迫使本作的热膨胀系数(不强制至少一个计划指南)
在这种情况下,您(通常)有3个选择。A @tablevariable,#localtemp一张桌子和一张##globaltemp桌子。但是,仅其中的第一个允许在函数内部使用。
@tablevariable
#localtemp
##globaltemp
有关表变量和#temp表之间差异的更多信息,请参见此处。