【发布时间】:2020-02-14 15:19:01
【问题描述】:
我是创建存储过程和函数的新手,我只是不明白为什么其中一个版本的运行速度比另一个快得多。这是一个在调用时只返回带有描述的字符串的函数。原始函数依赖于提供大约 10 个变量(版本在大约 4 秒内运行)。我想将其缩减为单个变量(运行时间较长的版本)。
变量声明下面的代码是相同的,唯一的区别是我试图从函数本身的适当位置提取变量,而不是在查询端提供它们。
即dbo.cf_NoRateReason(V1) 作为 ReasonCode 而不是 dbo.cf_NoRateReason(V1,V2,V3,V4,V5,V6,V7,V8,V9,V10,V11,V12)
如果我没有提供足够的信息,我先道歉,正如我所说的,新功能/存储过程。
此版本运行时间约为 2.5 分钟
declare @Agencyid int
declare @ServiceCode varchar(10)
declare @Mod1 varchar(2)=null
declare @Mod2 varchar(2)=null
declare @Mod3 varchar(2)=null
declare @Mod4 varchar(2)=null
declare @POS int
declare @ServiceDate datetime
declare @ProvType varchar(1)
declare @PayerID int
declare @BirthDate datetime
declare @RenderingStaffID int
declare @SupervisingStaffID int
Select @Agencyid=s.agencyid, @ServiceCode = ServiceCode,
@Mod1 = ModifierCodeId, @Mod2 = ModifierCodeId2,
@Mod3 = ModifierCodeId3, @Mod4 = ModifierCodeId4,
@POS=PlaceOfServiceId, @ServiceDate = ServiceDate,
@RenderingStaffId=isnull(dbo.GetProviderStaffId('S',s.ServiceTransactionId,'82'),0),
@SupervisingStaffId=isnull(dbo.GetProviderStaffId('C',ClaimId,'DQ'),0),
@ProvType=s.servicetype, @Payerid=pmt.payerid,
@BirthDate=i.birthdate
From ServiceTransaction s
join individual i on s.servicetransactionid = i.individualid
join pmtadjdetail pmt on s.servicetransactionid = pmt.servicetransactionid
declare @Result Varchar(100) = ''
declare @Age int = dbo.getageatservicedate(@birthdate, @ServiceDate)
declare @ModString varchar(8) = dbo.sortmodifiers(@Mod1, @Mod2, @Mod3, @Mod4)
declare @DirectSupervision int = (iif(@Mod1 in ('U1','U6','U7','U9','UA')
or @Mod2 in ('U1','U6','U7','U9','UA')
or @Mod3 in ('U1','U6','U7','U9','UA')
or @Mod4 in ('U1','U6','U7','U9','UA'),1,0))
'************************************************************************************'
'This version takes about 4 seconds to run'
'************************************************************************************'
begin
declare @Result Varchar(100) = ''
declare @Age int = dbo.getageatservicedate(@birthdate, @ServiceDate)
declare @RenderingStaffID int = dbo.getstaffid(@STID,'DQ')
declare @SupervisingStaffID int = dbo.getstaffid(@STID,'82')
declare @ModString varchar(8) = dbo.sortmodifiers(@Mod1, @Mod2, @Mod3, @Mod4)
declare @DirectSupervision int = (iif(@Mod1 in ('U1','U6','U7','U9','UA')
or @Mod2 in ('U1','U6','U7','U9','UA')
or @Mod3 in ('U1','U6','U7','U9','UA')
or @Mod4 in ('U1','U6','U7','U9','UA'),1,0))
【问题讨论】:
-
您首先列出的版本没有过滤器(没有 WHERE 子句)在它用来获取“参数”值的 SELECT 上它通常是通过了。您有效地获得了整个连接结果集,每个结果行的函数调用成本,并且只取最后一个结果的值。
-
标量函数在最好的情况下对性能来说是可怕的。最好使用表值参数或内联表值函数。
-
您的第一个查询中有一个以“选择 @Agencyid=s.agencyid, @ServiceCode = ServiceCode, ”等开头的查询,您可能想知道这需要多长时间
-
谢谢Uueerdo,你也是个天才!这正是问题所在
标签: sql-server function processing-efficiency