Sql server 功能效率

Sql server 功能效率,sql-server,function,processing-efficiency,Sql Server,Function,Processing Efficiency,我是创建存储过程和函数的新手,我就是不明白为什么这些版本中的一个运行得比另一个快得多。这是一个函数,调用时只返回一个带有描述的字符串。原始函数依赖于提供大约10个变量,该版本在大约4秒内运行。我想把它简化为一个长时间运行的单变量版本 变量声明下面的代码是相同的,唯一的区别是我试图从函数本身的适当位置提取变量,而不是在查询端提供它们 i、 e.dbo.cf_NoRateReasonV1作为理由代码 而不是 dbo.cf_NoRateReasonV1、V2、V3、V4、V5、V6、V7、V8、V9、

我是创建存储过程和函数的新手,我就是不明白为什么这些版本中的一个运行得比另一个快得多。这是一个函数,调用时只返回一个带有描述的字符串。原始函数依赖于提供大约10个变量,该版本在大约4秒内运行。我想把它简化为一个长时间运行的单变量版本

变量声明下面的代码是相同的,唯一的区别是我试图从函数本身的适当位置提取变量,而不是在查询端提供它们

i、 e.dbo.cf_NoRateReasonV1作为理由代码 而不是 dbo.cf_NoRateReasonV1、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))


你是对的-唯一的区别是使用函数。请看这是在哪里解决的

简言之,函数将逐行执行,而查询端的代码将具有其他选项,而不会对函数进行开销调用。 您可以使用带有模式绑定的标量函数,null返回null以获得更好的性能


对模式计划的额外考虑将是有价值的。这里还有连接和其他嵌入逻辑,如果没有样本数据,它们就不清楚。

这种类型属于打字错误或简单的疏忽,但是

当您看到巨大的性能差异时,由于不可识别的原因,这些函数也在原始版本中使用,这通常是您需要开始查找这些类型的错误的时候:打字错误、缺少条件、过于依赖intellisense/代码完成而导致的不正确条件,等等

当用一个可用于自动检索其他参数的参数替换多个参数时,始终确保实际使用该参数


首先列出的版本在SELECT上没有filter no WHERE子句,它用于获取通常传递的参数值。您实际上获得了整个连接结果集,每个结果行的函数调用成本都是如此,并且只获取最后一个结果的值。

您首先列出的版本在SELECT上没有filter no WHERE子句,它用于获取通常传递的参数值。实际上,您得到的是整个连接结果集,每个结果行的函数调用成本都很高,并且只取最后一个结果的值。在最好的情况下,标量函数的性能很差。最好使用表值参数或内联表值函数。您的第一个查询以“Select@Agencyid=s.Agencyid、@ServiceCode=ServiceCode”等开头。您可能想知道这需要多长时间。如果您愿意,您也是一个天才!这正是问题所在似乎更可能的是,他以“Select@Agencyid=s.Agencyid,@ServiceCode=ServiceCode”为起始的查询是问题所在,特别是正如Uuerdo所指出的,它可能会返回许多行,但只保留恰好返回的最后一行的值。谢谢,我会读你的建议。我正在使用与数据库中另一个标量值函数类似的过程,该函数的运行速度比我的快,在设置变量方面,我看不出我所做的与另一个函数所做的有什么区别,这似乎是挂起的地方。请检查Uuerdo的注释-除非有具有单行,看起来第一个过程中的查询返回了多条记录-您肯定需要缩小到一行-在SSMS窗口中隔离查询,将其更改为SELECT*,然后查看它得到了多少行SCATO,您是天才,我是白痴。您是100%正确的,我没有使用@STID变量将返回的数据集限制为单个记录。它现在在1秒内运行,而不是4秒@卡托似乎是正确的;我将把这个留给评论讨论,因为它是相关的。对不起,误会了。