任何人都可以帮我从SQL 2000中提高这个游标逻辑的性能。它在SQl2005和SQL2008中运行良好,但在SQL 2000中运行至少需要20分钟。顺便说一下,我永远不会选择使用游标,我没有编写这段代码,只是试图让它运行得更快。在不久的将来,将此客户端升级到2005/2008不是一种选择。
-------------------------------------------------------------------------------
------- Rollup totals in the chart of accounts hierarchy
-------------------------------------------------------------------------------
DECLARE @B_SubTotalAccountID int, @B_Debits money, @B_Credits money, @B_YTDDebits money, @B_YTDCredits money
DECLARE Bal CURSOR FAST_FORWARD FOR
SELECT SubTotalAccountID, Debits, Credits, YTDDebits, YTDCredits FROM xxx
WHERE AccountType = 0 AND SubTotalAccountID Is Not Null and (abs(credits)+abs(debits)+abs(ytdcredits)+abs(ytddebits)<>0)
OPEN Bal
FETCH NEXT FROM Bal INTO @B_SubTotalAccountID, @B_Debits, @B_Credits, @B_YTDDebits, @B_YTDCredits
--For Each Active Account
WHILE @@FETCH_STATUS = 0
BEGIN
--Loop Until end of subtotal chain is reached
WHILE @B_SubTotalAccountID Is Not Null
BEGIN
UPDATE xxx2
SET Debits = Debits + @B_Debits,
Credits = Credits + @B_Credits,
YTDDebits = YTDDebits + @B_YTDDebits,
YTDCredits = YTDCredits + @B_YTDCredits
WHERE GLAccountID = @B_SubTotalAccountID
SET @B_SubTotalAccountID = (SELECT SubTotalAccountID FROM xxx2 WHERE GLAccountID = @B_SubTotalAccountID)
END
FETCH NEXT FROM Bal INTO @B_SubTotalAccountID, @B_Debits, @B_Credits, @B_YTDDebits, @B_YTDCredits
END
CLOSE Bal
DEALLOCATE Bal
答案 0 :(得分:3)
Update xx2
Set Credits = Credits + X1.CreditTotal
, Debits = Debits + X1.DebitTotal
, YtdDebits = YtdDebits + X1.YtdDebitTotal
, YtdCredits = YtdCredits + X1.YtdDebitTotal
From xx2 As X2
Join (
Select SubTotalAccountID, Sum(Debits) As DebitTotal, Sum(Credits) As CreditTotal
, Sum(YtdDebits) As YtdDebitTotal, Sum(YtdCredits) As YtdCreditTotal
From xxx
Where AccountType = 0
And SubTotalAccountID Is Not Null
And (
Credits <> 0
Or Debits <> 0
Or YtdCredits <> 0
Or YtdDebits <> 0
)
Group By SubTotalAccountID
) As X1
On X1.SubTotalAccountID = X2.GLAccountID
如果没有架构,我无法判断xxx
表是否会为给定的SubTotalAccountId返回多行。我假设它可以并按此列对值进行分组,以便每个SubTotalAccountId得到一行。
我还在WHERE子句中替换了你对ABS的使用,只需检查零。这应该快得多。
此UPDATE语句应该是光标的完全替代。
答案 1 :(得分:1)
一些建议:
1 - 使用分析器告诉你哪一部分运行缓慢 - 你可以获得每个陈述的持续时间
2 - 在过程之外运行初始select语句(游标声明)并检查查询计划。它运行得很快吗?它是否正确使用索引?
3 - 与update语句相同 - 检查查询计划和索引用法
4 - 更新后的'set'语句看起来很奇怪 - 似乎是在@B_SubTotalAccountID中得到一个值,然后立即被'fetch next'替换