SP execution time is extremely slow

别说谁变了你拦得住时间么 提交于 2020-01-06 08:11:56

问题


I created a stored procedure that calculates a financial spreading based on a linear self adjusting rule and it takes more than 2 minutes to finish the calculations.

The final value goes through multiple iterations in order to adjust and enhance it till finding the optimal optimized final value. The parameters are the following:

@input1 = 100000
@input2 = 40
@input3 = 106833


BEGIN
DECLARE @X decimal(22,6) = 0
DECLARE @Y decimal(22,6) = 0.001 
DECLARE @Z decimal(22,6)
DECLARE @r decimal(22,6)
DECLARE @v decimal(22,6) 

SET @v = POWER(1/(1+ (@Y/12)), @input2)
    SET @r = ((@Y/@input2) * input1) / (1-@v) 
    IF (@r < @input3)
        SET @Z = @Y + ABS((@X - @Y)/2)
    ELSE
        SET @Z = @Y - ABS((@X - @Y) /2)

    SET @X = @Y
    SET @Y = @Z 


WHILE (ABS(@r - @input3) > 0.001)
BEGIN
SET @v = POWER(1/(1+ (@Y/12)), @input2)
    SET @r = ((@Y/@input2) * @input1) / (1-@v) 
    IF (@r < @input3)
         SET @Z = @Y + ABS((@X - @Y)/2)
    ELSE
         SET @Z = @Y - ABS((@X - @Y) /2)
    SET @X = @Y
    IF @Y = @Z
    BREAK
    SET @Y = @Z
END

RETURN (CAST(@Y AS decimal(22,6)) * 100)



END

run time = 2 mins and 20 seconds


回答1:


An alternative to your stored procedure written in TSQL might be a SQL CLR function written in C#. You have to use Visual Studio and create a Database Project.

    public static decimal ConvertTo6(double d)
    {
        return Math.Round(Convert.ToDecimal(d), 6, MidpointRounding.AwayFromZero);
    }

    public static decimal ConvertTo6(decimal d)
    {
        return Math.Round(d, 6, MidpointRounding.AwayFromZero);
    }


    [Microsoft.SqlServer.Server.SqlFunction]
    [return: SqlFacet(Precision = 22, Scale = 6)]
    public static SqlDecimal CalcFinancialSpreading(int input1 = 100000, int input2 = 40, int input3 = 106833)
    {
        decimal x = 0.000000m;
        decimal y = 0.001000m;
        decimal z;
        decimal r;
        decimal v;

        v = ConvertTo6(Math.Pow(1 / (1 + (Convert.ToDouble(y) / 12d)), input2));

        r = ConvertTo6(((y / input2) * input1) / (1 - v));

        if (r < input3)
        {
            z = y + Math.Abs((x - y) / 2);
            z = ConvertTo6(z);
        }
        else
        {
            z = y - Math.Abs((x - y) / 2);
            z = ConvertTo6(z);
        }

        x = y;
        y = z;

        while (Math.Abs(r - input3) > 0.001m)
        {
            v = ConvertTo6((Math.Pow(Convert.ToDouble(1 / (1 + (y / 12))), Convert.ToDouble(input2))));

            r = ((y / input2) * input1) / (1 - v);
            r = ConvertTo6(r);

            if (r < input3)
            {
                z = y + Math.Abs((x - y) / 2);
                z = ConvertTo6(z);
            }
            else
            {
                z = y - Math.Abs((x - y) / 2);
                z = ConvertTo6(z);
            }
            x = y;
            if (y == z) break;
            y = z;
        }

        decimal result = y * 100;

        return new SqlDecimal(result);
    }

Executed as C# code the result is received in 45 seconds on my machine vs. TSQL in 1 Min 56 seconds.

Kudos to @wikiCan by answering this one...



来源:https://stackoverflow.com/questions/58726514/sp-execution-time-is-extremely-slow

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!