存储过程提高了性能

Thi*_*ken 1 t-sql vb.net sql-server stored-procedures

我编写了一个与我的Visual Basic .NET代码完全相同的存储过程.现在我已经对它们进行了基准测试.使用while循环和for循环.但是两者都使用我的Visual Basic .NET代码给了我更糟糕的结果.有没有办法提高此代码的性能:

DECLARE @RelationCode nvarchar(50)
DECLARE @CompanyName nvarchar(256)
DECLARE @IncomingInvoice decimal(18, 2)
DECLARE @OutgoingInvoice decimal(18, 2)
DECLARE @Profit decimal(18, 2)
DECLARE @RelationTable as TABLE (RELATIONCODE nvarchar(10), COMPANY nvarhar(120))

INSERT INTO @RelationTable (RELATIONCODE, COMPANY) SELECT [fms].[dbo].[Relation].[RELATIONCODE], [fms].[dbo].[Relation].[COMPANYNAME] FROM [fms].[dbo].[Relation]

/* Result table */
DECLARE @RESULTTABLE TABLE (RelationCode nvarchar(50), Companyname nvarchar(256), IncomingInvoice nvarchar(50), OutgoingInvoice nvarchar(50), profit nvarchar(50))

WHILE EXISTS(SELECT * FROM @RelationTable)
BEGIN
SELECT TOP 1 @RelationCode = RELATIONCODE, @CompanyName = COMPANY FROM @RelationTable

    SELECT fmsTotalAmountIncoming INTO TempIncomingAmounts FROM (
            SELECT SUM(CASE WHEN fms1.currency != 'EUR'
                THEN fms1.amount * fms1.rate
            ELSE ISNULL(fms1.amount, 0) END) fmsTotalAmountIncoming
    FROM [fms].[dbo].[file] f
        INNER JOIN [fms].[dbo].[incominginvoiceline] fms1 ON 
       fms1.filenumber = CONVERT(NVARCHAR, f.filenumber)
    WHERE f.RELATIONCODE = @RelationCode
    ) a 

    SELECT fmsTotalAmountOutgoing INTO TempOutgoingAmounts FROM (
            SELECT SUM(CASE WHEN fms1.currency != 'EUR'
                THEN fms1.amount * fms1.rate
            ELSE ISNULL(fms1.amount, 0) END) fmsTotalAmountOutgoing
    FROM [fms].[dbo].[file] f
        INNER JOIN [fms].[dbo].[outgoinginvoiceline] fms1 ON 
       fms1.filenumber = CONVERT(NVARCHAR, f.filenumber)
    WHERE f.RELATIONCODE = @RelationCode
    ) a 
    SET @IncomingInvoice = (SELECT fmsTotalAmountIncoming FROM [fms].[dbo].[TempIncomingAmounts])
        SET @OutgoingInvoice = (SELECT fmsTotalAmountOutgoing FROM [fms].[dbo].[TempOutgoingAmounts])
        SET @Profit = ((@OutgoingInvoice - @IncomingInvoice) / @OutgoingInvoice)

        INSERT INTO @RESULTTABLE ([RELATIONCODE], [CompanyName], [IncomingInvoice], [OutgoingInvoice], [Profit])
                VALUES (@RelationCode, @CompanyName, @IncomingInvoice, @OutgoingInvoice, @Profit)

        DROP TABLE [fms].[dbo].[TempIncomingAmounts]
        DROP TABLE [fms].[dbo].[TempOutgoingAmounts]

        DELETE FROM @RelationTable WHERE RelationCode = @RelationCode
    END

    SELECT * FROM @RESULTTABLE
Run Code Online (Sandbox Code Playgroud)

我对此进行了基准测试,结果如下:

STORED PROCEDURE        VB.NET
6:54                    5:11
6:20                    5:11
6:19                    3:55
6:43                    4:01
Run Code Online (Sandbox Code Playgroud)

有没有人知道如何提高VB.net性能以上的性能,因为这种方式存储过程是没用的.

str*_*t01 6

您正在尝试在SQL中复制过程VB代码.SQL是基于集合的,只在此基础上运行良好.在不确切了解您的架构的情况下,这大致是您的SQL应该是什么样子,以便更快地获得您需要的结果:

;
WITH invoice (RELATIONCODE, COMPANYNAME, IncomingInvoice, OutgoingInvoice)
AS (
    SELECT r.[RELATIONCODE], r.[COMPANYNAME], 
    SUM(CASE WHEN fms1.currency != 'EUR'
            THEN fms1.amount * fms1.rate
        ELSE ISNULL(fms1.amount, 0) END) AS IncomingInvoice, 
    SUM(CASE WHEN fmso.currency != 'EUR'
            THEN fmso.amount * fmso.rate
        ELSE ISNULL(fmso.amount, 0) END) AS OutgoingInvoice
    FROM [fms].[dbo].[Relation] r
    LEFT OUTER JOIN [fms].[dbo].[file] f
    ON f.RELATIONCODE = r.[RELATIONCODE]
    LEFT OUTER JOIN [fms].[dbo].[incominginvoiceline] fms1
     ON fms1.filenumber = CONVERT(NVARCHAR, f.filenumber)
    LEFT OUTER JOIN [fms].[dbo].[outgoinginvoiceline] fmso
     ON fmso.filenumber = CONVERT(NVARCHAR, f.filenumber)
     GROUP BY r.[RELATIONCODE], r.[COMPANYNAME]
 )
 SELECT RELATIONCODE, 
    COMPANYNAME, 
    IncomingInvoice, 
    OutgoingInvoice,
     CASE WHEN OutgoingInvoice > 0 THEN (OutgoingInvoice - IncomingInvoice) / OutgoingInvoice 
    ELSE 0 END AS Profit
 FROM invoice
Run Code Online (Sandbox Code Playgroud)

即没有循环,if ... else语句,创建,删除然后重新创建永久表等.只有一个SQL语句按照关系代码和公司名对结果进行分组.

  • @ThimoFranken您没有提供架构或数据示例,因此您无法获得完美的结果.谁能猜出哪些字段可以为空,哪些字段不可以?strickt01在将循环重写为查询方面做得非常出色 (4认同)