Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • Home
  • SEARCH
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 3271396
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 17, 20262026-05-17T18:43:28+00:00 2026-05-17T18:43:28+00:00

I have a stored procedure that uses a FAST_FORWARD cursor to chronologically loop over

  • 0

I have a stored procedure that uses a FAST_FORWARD cursor to chronologically loop over a set of ~300k records and assigns them to declaration sets based on the state of a lot of running variables and flags, partly implemented as table variables. I have given a lot of thought on how to do this set-based and I just can’t do it. So I am stuck with the cursor approach, and need to optimize this code.

What I have noticed is that the first 10% of progress is loaded and processed very quickly (2000 rows/sec), near 20% progress it has slowed to about 300 rows/sec and in the end it has slowed down to about 60 rows/sec.

IMO this can be due to 4 reasons:

  • The cursor slows down, which I would think unlikely with a FAST_FORWARD cursor
  • The processing slows down. For my “groups” I am using table variables in which I am inserting, updating and deleting. At any given moment there are max. about 10 rows in those variables.
  • The inserting into target tables slows down. I don’t see why this would be, I have no triggers defined on them and they are just ordinary tables.
  • Evil magic

Either that or my percentage counter is broken:

SET @curprogress = @curprogress + 1
IF (@curprogress - ((@totprogress / 100) * (FLOOR(@curprogress * 100 / @totprogress)))) BETWEEN 0 AND 1 BEGIN
    SET @msg = CAST(FLOOR(@curprogress * 100 / @totprogress) AS VARCHAR)
    RAISERROR('%s%s', 0, 1, @msg, '%...') WITH NOWAIT;
END

Has anybody any clue what to look for and how to go on speeding up this query?

Symbolic exerpt of my code:

WHILE....
-- Fetch new record to be assigned to one of the open declaration sets
FETCH NEXT INTO @row_field1, @row_field2....
IF (@flag2 = 1) AND ((@flag1 = 0) OR (@row_field1 <> @prevrow_field1)) 
BEGIN
    -- Logging info: we are closing a child declaration set
    INSERT INTO @logtable SELECT '--> LOG MESSAGE'
    INSERT INTO @logtable
    SELECT format_message(@row_field1, @calc_field2, field3...)
    FROM @runningtable_sub S LEFT JOIN @runningtable_main M ON S.MainID = M.ID

    -- Update enddate of parent
    UPDATE M SET M.enddate = DATEADD(day,365,S.enddate)
    FROM @runningtable_sub S
    LEFT JOIN @runningtable_main M
    ON S.MainID = M.ID

    -- close and save child
    INSERT INTO outputtable_main
    SELECT @field1, COALESCE(Z.Field1,'NULL'), S.startdate, S.enddate,
        M.Startdate, M.Enddate
    FROM @runningtable_sub S 
    LEFT JOIN @runningtable_main M ON S.MainID = M.ID

    -- delete child from running table
    DELETE FROM @runningtable_sub WHERE S.enddate < @curdate
END
  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-17T18:43:28+00:00Added an answer on May 17, 2026 at 6:43 pm

    I could think of lots of reasons this is slowing down, but it is hard to narrow it down without knowing the cardinality of your data.

    Random observations:

    1. Your format_message() function is surely a dog; all UDFs are. But how many rows are you inserting per pass?
    2. @runningtable_main never gets cleared out.
    3. updates are expensive
    4. deletes are expensive. If you use temp tables and rework your implementation, you can truncate instead of delete

    To figure some of it out for yourself, add instrumentation:

    DECLARE @now DATETIME, @duration INT, @rowcount INT
    
    WHILE....
    -- Fetch new record to be assigned to one of the open declaration sets
    FETCH NEXT INTO @row_field1, @row_field2....
    IF (@flag2 = 1) AND ((@flag1 = 0) OR (@row_field1 <> @prevrow_field1)) 
    BEGIN
        PRINT '---------------'
    
        -- Logging info: we are closing a child declaration set
        INSERT INTO @logtable SELECT '--> LOG MESSAGE'
        SET @now = GETDATE()
        INSERT INTO @logtable
        SELECT format_message(@row_field1, @calc_field2, field3...)
        FROM @runningtable_sub S LEFT JOIN @runningtable_main M ON S.MainID = M.ID
        SELECT @rowcount = @@ROWCOUNT, @duration = DATEDIFF(ms,@now,GETDATE)
        RAISERROR('%i row(s) inserted into @logtable, %i milliseconds',-1,-1,@rowcount,@duration) WITH NOWAIT
    
        -- Update enddate of parent
        SET @now = GETDATE()
        UPDATE M SET M.enddate = DATEADD(day,365,S.enddate)
        FROM @runningtable_sub S
        LEFT JOIN @runningtable_main M
        ON S.MainID = M.ID
        SELECT @rowcount = @@ROWCOUNT, @duration = DATEDIFF(ms,@now,GETDATE)
        RAISERROR('%i row(s) updated in @runningtable_main, %i milliseconds',-1,-1,@rowcount,@duration) WITH NOWAIT
    
        -- close and save child
        SET @now = GETDATE()
        INSERT INTO outputtable_main
        SELECT @field1, COALESCE(Z.Field1,'NULL'), S.startdate, S.enddate,
            M.Startdate, M.Enddate
        FROM @runningtable_sub S 
        LEFT JOIN @runningtable_main M ON S.MainID = M.ID
        SELECT @rowcount = @@ROWCOUNT, @duration = DATEDIFF(ms,@now,GETDATE)
        RAISERROR('%i row(s) inserted into outputtable_main, %i milliseconds',-1,-1,@rowcount,@duration) WITH NOWAIT
    
        -- delete child from running table
        SET @now = GETDATE()
        DELETE FROM @runningtable_sub WHERE S.enddate < @curdate
        SELECT @rowcount = @@ROWCOUNT, @duration = DATEDIFF(ms,@now,GETDATE)
        RAISERROR('%i row(s) deleted from @runningtable_sub, %i milliseconds',-1,-1,@rowcount,@duration) WITH NOWAIT
    END
    

    If you included your entire code (including the cursor declaration), rather than just a symbolic excerpt, someone here could probably rework it for you to be much more efficient and/or avoid cursors all together.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I have a stored procedure that works fine on its own. A recent requirement
Working in SQL Server 2005, I have a stored procedure that inserts a record
So, I have an app that uses a SQL Server express db. I have
I have a web application at work that is similar to a ticket working
I have an windows application in VB.NET (2.0) and Oracle Database, the connections are
We build software using Hudson and Maven. We have C#, java and last, but
This is a follow-up from this question . Functions are not allowed to write
I've converted a bunch of reports from Crystal Reports 7 to Crystal Reports 2008
Consider a table with a column amount, Amount -1235.235 1356.45 -133.25 4565.50 5023 -8791.25
I think I've got a fundamental misunderstanding going on, concerning a SQL Server Reporting

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.