2

誰かが私にSQL2000からこのカーソルロジックのパフォーマンスを改善する手を差し伸べることができますか?それは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
4

2 に答える 2

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ごとに1つの行を取得できるように、この列で値をグループ化できると想定しました。

また、WHERE句でのABSの使用を、単にゼロに対してチェックするように置き換えました。これは大幅に高速になるはずです。

このUPDATEステートメントは、カーソルを完全に置き換える必要があります。

于 2010-04-16T15:18:34.883 に答える
1

いくつかの提案:

1-プロファイラーを使用して、実行速度が遅い部分を通知します-各ステートメントの期間を取得できます

2-プロシージャの外で最初のselectステートメント(カーソル宣言)を実行し、クエリプランを確認します。速く走りますか?インデックスを適切に使用していますか?

3-updateステートメントと同じこと-クエリプランとインデックスの使用法を確認する

4-更新後の「set」ステートメントは奇妙に見えます-@B_SubTotalAccountIDに値を取得しているようで、すぐに「fetchnext」に置き換えられます

于 2010-04-16T14:50:08.660 に答える