【发布时间】:2018-06-30 15:47:14
【问题描述】:
性能调优差继承 SQL Server 中的 UDF。
最近我获得了一个新的 SQL Server 环境。我已经能够更快地制作不同的部分,但我在使用这个调用两个标量值函数的表值函数时遇到了问题。问题是性能调优 UDF 是我很新的东西之一,我想要一些帮助来帮助我如何让它更快。
我了解标量值函数用于逐行处理。所以我正在寻找一种方法来加快速度。有人可以帮忙吗。下面是函数。
标量值函数 1. 添加这个只是为了显示发生了什么。
ALTER FUNCTION [dbo].[AgingFactorOverride]
(@Aging_Factor FLOAT,
@Company_ID INT,
@Survey_ID INT,
@Country_Code VARCHAR(50),
@Effective_Date DATETIME)
RETURNS FLOAT
WITH EXEC AS CALLER
AS
BEGIN
DECLARE @RetVal FLOAT
BEGIN
SELECT @RetVal = MAX(Aging_Factor)
FROM companysurveycountryaging csca
WHERE csca.company_id = @Company_ID
AND csca.Country_Code = @Country_Code
AND ISNULL(csca.survey_id, '') = CASE WHEN csca.survey_id IS NOT NULL
THEN @Survey_ID
ELSE ''
END
AND csca.effective_date = (SELECT MAX(cscaa.effective_date)
FROM companysurveycountryaging cscaa
WHERE cscaa.company_id = @Company_ID
AND cscaa.Country_Code = @Country_Code
AND ISNULL(cscaa.survey_id, '') = CASE WHEN cscaa.survey_id IS NOT NULL THEN @Survey_ID ELSE '' END
AND cscaa.effective_date <= @Effective_Date)
IF @RetVal IS NULL
BEGIN
SET @RetVal = @Aging_Factor
END
END
RETURN @RetVal
END
标量值函数2。
ALTER FUNCTION [dbo].[AgeData]
(@ValToAge float, @StartDate datetime, @EndDate datetime, @AgingFactor float)
RETURNS float
WITH EXEC AS CALLER
AS
BEGIN
Declare @RetVal float,@NumMonths float
if @AgingFactor is not NULL
Begin
Set @NumMonths=DateDiff(month,@StartDate,@EndDate);
Set @RetVal=@ValToAge*(1+(((@AgingFactor/12)*@NumMonths)/100));
End
else
set @RetVal=@ValToAge;
Return @RetVal
END
表值函数——这是调用上述标量函数的查询示例。
Select
@Base25=ISNULL(dbo.AgeData(sd.base25,s.effective_Date,@Effective_Date,dbo.AgingFactorOverride(cs.aging_factor,@Company_ID,sd.Survey_ID,sd.Country_Code,@Effective_Date)),0),
@Base50=ISNULL(dbo.AgeData(sd.base50,s.effective_Date,@Effective_Date,dbo.AgingFactorOverride(cs.aging_factor,@Company_ID,sd.Survey_ID,sd.Country_Code,@Effective_Date)),0),
@Base75=ISNULL(dbo.AgeData(sd.base75,s.effective_Date,@Effective_Date,dbo.AgingFactorOverride(cs.aging_factor,@Company_ID,sd.Survey_ID,sd.Country_Code,@Effective_Date)),0),
@BaseAVG=ISNULL(dbo.AgeData(sd.baseAVG,s.effective_Date,@Effective_Date,dbo.AgingFactorOverride(cs.aging_factor,@Company_ID,sd.Survey_ID,sd.Country_Code,@Effective_Date)),0),
@TCC25=ISNULL(dbo.AgeData(sd.TCC25,s.effective_Date,@Effective_Date,dbo.AgingFactorOverride(cs.aging_factor,@Company_ID,sd.Survey_ID,sd.Country_Code,@Effective_Date)),0),
@TCC50=ISNULL(dbo.AgeData(sd.TCC50,s.effective_Date,@Effective_Date,dbo.AgingFactorOverride(cs.aging_factor,@Company_ID,sd.Survey_ID,sd.Country_Code,@Effective_Date)),0),
@TCC75=ISNULL(dbo.AgeData(sd.TCC75,s.effective_Date,@Effective_Date,dbo.AgingFactorOverride(cs.aging_factor,@Company_ID,sd.Survey_ID,sd.Country_Code,@Effective_Date)),0),
@TCCAVG=ISNULL(dbo.AgeData(sd.TCCAVG,s.effective_Date,@Effective_Date,dbo.AgingFactorOverride(cs.aging_factor,@Company_ID,sd.Survey_ID,sd.Country_Code,@Effective_Date)),0),
@Base10=ISNULL(dbo.AgeData(sd.Base10,s.effective_Date,@Effective_Date,dbo.AgingFactorOverride(cs.aging_factor,@Company_ID,sd.Survey_ID,sd.Country_Code,@Effective_Date)),0),
@Base90=ISNULL(dbo.AgeData(sd.Base90,s.effective_Date,@Effective_Date,dbo.AgingFactorOverride(cs.aging_factor,@Company_ID,sd.Survey_ID,sd.Country_Code,@Effective_Date)),0),
from surveydata sd, surveys s,companysurveys cs
where cs.company_id=s.Company_ID and cs.survey_id=s.survey_id and s.survey_id=sd.survey_id
如果您需要其他任何东西来使这项工作更好,请告诉我。
【问题讨论】:
-
欢迎来到 StackOverflow。请阅读如何提问部分以提出更好的问题。谢谢。 stackoverflow.com/help/how-to-ask
-
也许它没有坏,在这种情况下不要修复它。
-
Bad habits to kick : using old-style JOINs - 旧式 逗号分隔的表格列表 样式已替换为 ANSI 中的 proper ANSI
JOIN语法-92 SQL 标准(25 多年前),不鼓励使用它
标签: sql sql-server performance user-defined-functions