One of the fundamentals of loop optimization is that you should move stable operations outside of the loop. What I want to know is - if this is such a fundamental rule, why do so many people break it?!?
If you are familiar with other programming languages, then you are probably aware of loop optimization techniques. You should try to put all operations outside of the loop if they don’t need to change within the loop. This reduces the amount of unnecessary repetitive work. SQL Server optimizer doesn’t automatically recognize such inefficiencies and clean the code for you (compilers of some other languages do). You have to write efficient loops yourself as in the following example.
These scripts print a table of square roots for all numbers from 1 to 100. Notice the boldfaced code below:
-- Loop with code inside = inefficient
SET NOCOUNT ON
DECLARE @message VARCHAR(25), @counter SMALLINT
SELECT @counter = 0
WHILE @counter < 100
BEGIN
SET @counter = @counter + 1
SET @message = REPLICATE( '-', 25 )
PRINT @message
SET @message = str( @counter, 10 ) + str( SQRT( CONVERT( FLOAT, @counter ) ), 10, 4 )
PRINT @message
END
-- Elapsed time: 376 ms
Compare the above Transact-SQL script to the one below, where the boldfaced code is moved outside of the loop:
-- Loop with code outside = efficient
SET NOCOUNT ON
DECLARE @separator VARCHAR(25), @message VARCHAR(25), @counter SMALLINT
SELECT @counter = 0,
@separator = REPLICATE( '-', 25 )WHILE @counter < 100
BEGIN
SET @counter = @counter + 1
PRINT @separator
SET @message = Str( @counter, 10 ) + Str( SQRT( CONVERT( FLOAT, @counter ) ), 10, 4 )
PRINT @message
END
-- Elapsed time: 36 ms
The second script executes the REPLICATE( ‘-‘, 25 ) function only once, compared to 100 times in the first script. Results produced by both scripts are identical:
-------------------------
1 1.0000
-------------------------
2 1.4142
-------------------------
3 1.7321
-------------------------
4 2.0000
. . .
. . .
. . .
-------------------------
99 9.9499
-------------------------
100 10.0000
Of course, there are a million and one ways to perform any such algorithm. But I'm still surprised that otherwise experienced and competent database programmers are still embedding very stable elements of their code inside of extensive looping operations rather than outside of them. Thoughts?
Cheers,
-Kev
Twitter @ kekline