存储过程执行时间很长

问题描述 投票:0回答:1
IF(@PAGEFROM='SALESINVOICE')
BEGIN
INSERT INTO TBL_ACCOUNTTRANSACTION(
ReferenceNo, Date, NepaliDate, LedgerID, BankName, Debit, Credit, Balance, PageFrom, UCDRAmount, UCCRAmount, GroupID, SubGroup, 
CategoryID, AccountType, SubType, Currency, Subledger, Agent, Narration, Remarks, PartyNo, PartyDate, CreatedBy,LStatus
)
SELECT INVOICENO,DATE,NEPALIDATE,CASE WHEN TYPE='1' THEN '1' ELSE VENDOR END,'',
case when TotalAmt='0.00' then TermAmt else TotalAmt end,'0.00','0.00','SB','0.00','0.00',lai.groupid,
SubGroupID,lai.CategoryID,lai.AccountType,MAS.AccountSubType,'0.00',
CASE WHEN SI.SubLedger IS NULL THEN '' ELSE SI.SubLedger END,
CASE WHEN AgentID IS NULL THEN '' ELSE AGENTID END,'',Remarks,'','',SI.CREATEDBY,'U'
FROM TBL_SALESINVOICE SI
LEFT JOIN TBL_LEDGERACCINFO LAI ON LAI.LEDGERID= CASE WHEN TYPE='1' THEN 1 ELSE SI.VENDOR END
LEFT JOIN TBL_ACCOUNTGROUP AG ON AG.ACCOUNTGROUPID=LAI.GROUPID
LEFT JOIN TBL_MASTERACCOUNTSUBTYPE AS MAS ON MAS.ACCOUNTSUBTYPEID=AG.ACCOUNTSUBTYPEID 
LEFT JOIN TBL_CATEGORY CG ON CG.CATEGORYID=LAI.CATEGORYID
WHERE INVOICENO=@NO

UNION ALL
SELECT SIP.INVOICENO,DATE,NEPALIDATE,SALESLEDGER,'','0.00',SUM(BasicAmount),'0.00','SB','0.00','0.00',lai.groupid,
SubGroupID,lai.CategoryID,lai.AccountType,MAS.AccountSubType,'0.00','','','','','','',SIP.CREATEDBY,'L'
FROM TBL_SALESINVOICEPRODUCT SIP
LEFT JOIN TBL_SALESINVOICE SI ON SI.INVOICENO=SIP.INVOICENO
LEFT JOIN TBL_LEDGERACCINFO LAI ON LAI.LEDGERID=SIP.SALESLEDGER
LEFT JOIN TBL_ACCOUNTGROUP AG ON AG.ACCOUNTGROUPID=LAI.GROUPID
LEFT JOIN TBL_MASTERACCOUNTSUBTYPE AS MAS ON MAS.ACCOUNTSUBTYPEID=AG.ACCOUNTSUBTYPEID 
LEFT JOIN TBL_CATEGORY CG ON CG.CATEGORYID=LAI.CATEGORYID
WHERE SIP.INVOICENO=@NO
GROUP BY SIP.INVOICENO,DATE,NEPALIDATE,SALESLEDGER,lai.groupid,
SubGroupID,lai.CategoryID,lai.AccountType,MAS.AccountSubType,SIP.CREATEDBY 

UNION ALL
SELECT
SD.CHALLANNO,DATE,NEPALIDATE,SB.LEDGERID,'',
SUM(abs (CASE WHEN (Amount<0) THEN AMOUNT ELSE '0.00' END)),  
SUM(abs (CASE WHEN (Amount>0) THEN AMOUNT ELSE '0.00' END)),
'0.00','SB','0.00','0.00',lai.groupid,SubGroupID,lai.CategoryID,
lai.AccountType,MAS.AccountSubType,'0.00','','','','','','',SD.CREATEDBY,'L'
FROM TBL_SALESBILLING SB   
LEFT JOIN TBL_SALESDISCOUNT SD ON SB.DESCRIPTION=SD.DESCRIPTION    
LEFT JOIN TBL_SALESINVOICE SI ON SI.INVOICENO=SD.CHALLANNO
LEFT JOIN TBL_LEDGERACCINFO LAI ON LAI.LEDGERID=SB.LEDGERID
LEFT JOIN TBL_ACCOUNTGROUP AG ON AG.ACCOUNTGROUPID=LAI.GROUPID
LEFT JOIN TBL_MASTERACCOUNTSUBTYPE AS MAS ON MAS.ACCOUNTSUBTYPEID=AG.ACCOUNTSUBTYPEID 
LEFT JOIN TBL_CATEGORY CG ON CG.CATEGORYID=LAI.CATEGORYID
WHERE PageFrom ='SALESINVOICE' AND SD.CHALLANNO=@NO
GROUP BY 
SD.CHALLANNO,DATE,NEPALIDATE,SB.LEDGERID,lai.groupid,SubGroupID,lai.CategoryID,lai.AccountType,MAS.AccountSubType,SD.CREATEDBY

UNION ALL
SELECT
INVOICENO,DATE,NEPALIDATE,SB.LEDGERID,'',
(abs (CASE WHEN (Amount<0) THEN AMOUNT ELSE '0.00' END)),  
(abs (CASE WHEN (Amount>0) THEN AMOUNT ELSE '0.00' END)),
'0.00','SB','0.00','0.00',lai.groupid,SubGroupID,lai.CategoryID,
lai.AccountType,MAS.AccountSubType,'0.00','','','','','','',SBT.CREATEDBY,'L'
FROM TBL_SALESBILLING SB   
LEFT JOIN TBL_SALESBILLTERM SBT ON SB.DESCRIPTION=SBT.DESCRIPTION    
LEFT JOIN TBL_SALESINVOICE SI ON SI.INVOICENO=SBT.CHALLANNO
LEFT JOIN TBL_LEDGERACCINFO LAI ON LAI.LEDGERID=SB.LEDGERID
LEFT JOIN TBL_ACCOUNTGROUP AG ON AG.ACCOUNTGROUPID=LAI.GROUPID
LEFT JOIN TBL_MASTERACCOUNTSUBTYPE AS MAS ON MAS.ACCOUNTSUBTYPEID=AG.ACCOUNTSUBTYPEID 
LEFT JOIN TBL_CATEGORY CG ON CG.CATEGORYID=LAI.CATEGORYID
WHERE PageFrom ='SALESINVOICE' AND AMOUNT<>'0.00' AND INVOICENO=@NO

    DECLARE INVOICENO 
    CURSOR local FOR Select DISTINCT AT.LEDGERID,ACCOUNTNAME FROM TBL_ACCOUNTTRANSACTION AT 
    LEFT JOIN TBL_LEDGERACCINFO LAI ON LAI.LEDGERID=AT.LEDGERID
    WHERE PAGEFROM='SB' AND REFERENCENO=@NO
    UNION ALL
    Select DISTINCT AT.ELEDGERID,ACCOUNTNAME FROM TBL_ACCOUNTTRANSACTION AT 
    LEFT JOIN TBL_LEDGERACCINFO LAI ON LAI.LEDGERID=AT.ELEDGERID
    WHERE PAGEFROM='SB' AND AT.LEDGERID<>ELEDGERID AND ELEDGERID<>'' AND REFERENCENO=@NO 

    OPEN INVOICENO
    FETCH FROM INVOICENO INTO @LEDGERID,@ACCOUNTNAME
    WHILE (@@FETCH_STATUS = 0) 
    BEGIN 
        Exec RunningTotal @ACCOUNTNAME       
        FETCH NEXT FROM INVOICENO INTO @LEDGERID,@ACCOUNTNAME
    END
END

我最近加入了一家公司,并接受了优化存储过程的任务。以上是存储过程的一部分。问题是这个存储过程中有4个类似的查询:采购发票、采购退货、销售发票和销售退货,并且执行时间很长,可能是数据的原因,因为表中有相当大的数据,但我也觉得它与存在和使用的连接有关。如果您需要大约 400 行代码的完整存储过程,请告诉我。

这是我收到的错误消息
SQL ERROR

我尝试在从互联网上查找的表中使用聚集索引,但我认为这没有任何区别

sql sql-server performance sql-execution-plan
1个回答
0
投票

在我们看到查询背后的数据和模式之前,并不总是清楚是什么导致查询变慢。例如。行数、数据类型、键和约束。示例数据点总是有帮助的。

尽管如此,我注意到您正在为光标中的每一行执行一个过程(

EXEC RunningTotal
INVOICENO
。作为一般原则,只要有可能使用标准表表达式表达相同的逻辑,就应该避免使用游标,因为它们强制对行进行迭代,这可能会降低效率。

对于行数较多的大型数据集尤其如此。正如这篇文章中所表达的:

当我们处理OLTP环境和大量数据时 过程中,不应说出“CURSOR”一词。

表名称表明我们正在处理可能包含许多行的金融交易表,这是游标的禁忌。

我将首先研究您是否可以重构此

UNION
以将逻辑合并到过程
RunningTotal
中,作为单个表表达式(即没有光标)。

Select DISTINCT AT.LEDGERID,ACCOUNTNAME FROM TBL_ACCOUNTTRANSACTION AT 
LEFT JOIN TBL_LEDGERACCINFO LAI ON LAI.LEDGERID=AT.LEDGERID
WHERE PAGEFROM='SB' AND REFERENCENO=@NO
UNION ALL
Select DISTINCT AT.ELEDGERID,ACCOUNTNAME FROM TBL_ACCOUNTTRANSACTION AT 
LEFT JOIN TBL_LEDGERACCINFO LAI ON LAI.LEDGERID=AT.ELEDGERID
WHERE PAGEFROM='SB' AND AT.LEDGERID<>ELEDGERID AND ELEDGERID<>'' AND REFERENCENO=@NO 

如果没有示例数据和表架构,将很难提出更多建议。

© www.soinside.com 2019 - 2024. All rights reserved.