Hi All,
I know that SQL server cursors are general a bad idea and the first thing to
go when optimizing. They're heavy and slow and generally avoidable. On
occasion it can happen that you get stuck with an SP that you need to
optimize and moving it to dynamic SQL is not an option (even though speed
wise it would be better). So here's my question for all those DB experts.
I have logic that requires me to get a list of rows from one table and take
each row and execute another SP using that rows data. Which is faster
1. FAST_FORWARD CURSOR
OR
2. WHILE LOOP THAT CHECKS TILL COUNT = 0 AND INSIDE THE LOOP DOING A SELECT
TOP 1 TO GET MY ROW DATA AND REMOVING THE ROW FROM THE TEMP TABLE
The cursor is easier to understand code and seems like less queries but it's
a dreaded evil cursor. My test db is small so it's hard for me to see major
performance differences so I'm hoping somebody knows the answer already. Eve
n
with my small data, once I got the endless recursion solved, it seems like
the while loop might actually be faster (hard to tell though).
Is there a 3 way to achieve this functionality?
Oh yeah and I can't use the query analyzer to analyze the performance since
some of my inner sp's use temp tables (to avoid using CURSORS).No one will be able to say for sure... This is one of those things you'll
have to test... If cursors work better, then use them...
Wayne Snyder, MCDBA, SQL Server MVP
Mariner, Charlotte, NC
www.mariner-usa.com
(Please respond only to the newsgroups.)
I support the Professional Association of SQL Server (PASS) and it's
community of SQL Server professionals.
www.sqlpass.org
"lee" <lee@.discussions.microsoft.com> wrote in message
news:64E22F44-072E-44E5-AA43-EE7EE5398F5C@.microsoft.com...
> Hi All,
> I know that SQL server cursors are general a bad idea and the first thing
> to
> go when optimizing. They're heavy and slow and generally avoidable. On
> occasion it can happen that you get stuck with an SP that you need to
> optimize and moving it to dynamic SQL is not an option (even though speed
> wise it would be better). So here's my question for all those DB experts.
> I have logic that requires me to get a list of rows from one table and
> take
> each row and execute another SP using that rows data. Which is faster
> 1. FAST_FORWARD CURSOR
> OR
> 2. WHILE LOOP THAT CHECKS TILL COUNT = 0 AND INSIDE THE LOOP DOING A
> SELECT
> TOP 1 TO GET MY ROW DATA AND REMOVING THE ROW FROM THE TEMP TABLE
> The cursor is easier to understand code and seems like less queries but
> it's
> a dreaded evil cursor. My test db is small so it's hard for me to see
> major
> performance differences so I'm hoping somebody knows the answer already.
> Even
> with my small data, once I got the endless recursion solved, it seems like
> the while loop might actually be faster (hard to tell though).
> Is there a 3 way to achieve this functionality?
> Oh yeah and I can't use the query analyzer to analyze the performance
> since
> some of my inner sp's use temp tables (to avoid using CURSORS).
>|||"lee" <lee@.discussions.microsoft.com> wrote in message
news:64E22F44-072E-44E5-AA43-EE7EE5398F5C@.microsoft.com...
> Hi All,
> I know that SQL server cursors are general a bad idea and the first thing
to
> go when optimizing. They're heavy and slow and generally avoidable. On
> occasion it can happen that you get stuck with an SP that you need to
> optimize and moving it to dynamic SQL is not an option (even though speed
> wise it would be better). So here's my question for all those DB experts.
> I have logic that requires me to get a list of rows from one table and
take
> each row and execute another SP using that rows data. Which is faster
> 1. FAST_FORWARD CURSOR
> OR
> 2. WHILE LOOP THAT CHECKS TILL COUNT = 0 AND INSIDE THE LOOP DOING A
SELECT
> TOP 1 TO GET MY ROW DATA AND REMOVING THE ROW FROM THE TEMP TABLE
> The cursor is easier to understand code and seems like less queries but
it's
> a dreaded evil cursor. My test db is small so it's hard for me to see
major
> performance differences so I'm hoping somebody knows the answer already.
Even
> with my small data, once I got the endless recursion solved, it seems like
> the while loop might actually be faster (hard to tell though).
> Is there a 3 way to achieve this functionality?
> Oh yeah and I can't use the query analyzer to analyze the performance
since
> some of my inner sp's use temp tables (to avoid using CURSORS).
>
Instead of doing a TOP 1 and then deleting, you could create an IDENTITY
column and skip the delete. It will probably be faster than doing the
deletes on a large lookup table.
DECLARE @.tmp TABLE (IDCol IDENTITY(1,1), SomeValue nvarchar(100))
DECLARE @.i int
DECLARE @.Lookup nvarchar(100)
INSERT @.tmp (SomeValue)
SELECT Value FROM LookupTable
SELECT @.i = COUNT(*) FROM @.tmp
WHILE @.i > 0
BEGIN
-- Get lookup value from temp table
SELECT @.Lookup = Value FROM @.tmp WHERE @.tmp.IDCol = @.i
-- Process
EXEC SomeProc @.Lookup
SET @.i = @.i - 1
END
Rick Sawtell
MCT, MCSD, MCDBA|||As I was reviewing my SPs, I realized that and implemented something similar
.
Speed increase when I did that was minimal but any speed increase is welcome
d
at this stage.
I've just done what I didn't want to do. I've started grouping a lot of the
SP's into single large SPs that can handle some of the load in batch queries
.
Speed increase is dramatic when doing this.
I've gone from 23 seconds (on my dev machine with no indexes) to traverse
20000 records in 16 tables to about 11 seconds. Speed is better but the
maintenance team is going to hate me for this.
FYI: From my tests the FAST_FOWARD cursor is faster then the While loop.
I've left the While loop in places with Large amount of rows and Cursor in
places with small amount of rows. Seems to be the best of both worlds so far
.
"Rick Sawtell" wrote:
> "lee" <lee@.discussions.microsoft.com> wrote in message
> news:64E22F44-072E-44E5-AA43-EE7EE5398F5C@.microsoft.com...
> to
> take
> SELECT
> it's
> major
> Even
> since
> Instead of doing a TOP 1 and then deleting, you could create an IDENTITY
> column and skip the delete. It will probably be faster than doing the
> deletes on a large lookup table.
> DECLARE @.tmp TABLE (IDCol IDENTITY(1,1), SomeValue nvarchar(100))
> DECLARE @.i int
> DECLARE @.Lookup nvarchar(100)
>
> INSERT @.tmp (SomeValue)
> SELECT Value FROM LookupTable
> SELECT @.i = COUNT(*) FROM @.tmp
> WHILE @.i > 0
> BEGIN
> -- Get lookup value from temp table
> SELECT @.Lookup = Value FROM @.tmp WHERE @.tmp.IDCol = @.i
> -- Process
> EXEC SomeProc @.Lookup
> SET @.i = @.i - 1
> END
>
> Rick Sawtell
> MCT, MCSD, MCDBA
>
>
>
>
>sql
Subscribe to:
Post Comments (Atom)
No comments:
Post a Comment