• If you always want the numbers table to start at 1, this demonstrates both an alternative to the function and a comparison of run times from 10 rows to 10 million rows...

    --===== Setup the test environment

        SET NOCOUNT ON --Supress the auto-display of rowcounts for appearance & speed

    --===== Declare local variables

    DECLARE @DesiredRows INT        --Number of rows desired in the result object

    DECLARE @StartTime   DATETIME   --For calculation of duration times

    --================================================================================

    --===== Loop through the tests from 10 to 10 million =============================

        SET @DesiredRows = 10

      WHILE @DesiredRows <= 10000000

      BEGIN

    --================================================================================

    --      Test the SELECT/INTO Method (temp table)

    --================================================================================

    --===== If the temporary Tally (Numbers) table exists, drop it

         -- (Included just for test repeatability.  Should not have to do in real life

         -- because won't exist when new connection starts)

         IF OBJECT_ID('TempDB..#Tally','U') IS NOT NULL

            DROP TABLE #Tally

    --===== Limit the desired number of rows

        SET ROWCOUNT @DesiredRows

    --===== Start the timer and run the test

        SET @StartTime = GETDATE()

     SELECT IDENTITY(INT,1,1) AS N

       INTO #Tally

       FROM Master.dbo.SysColumns sc1 WITH (NOLOCK),

            Master.dbo.SysColumns sc2 WITH (NOLOCK)

    --===== Report the rowcount and duration in seconds

      PRINT STR(@@ROWCOUNT) + ' Rows Inserted '

          + CONVERT(CHAR(13),GETDATE()-@StartTime,114) + ' Duration SELECT/INTO Method'

    --===== Return to normal unlimited rowcounts

        SET ROWCOUNT 0

    --================================================================================

    --      Test the F_TABLE_NUMBER_RANGE Method (table variables)

    --      Function F_TABLE_NUMBER_RANGE available on this link  

    --      http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=47685  

    --================================================================================

    --===== Start the timer and run the test

        SET @StartTime = GETDATE()

    DECLARE @N TABLE(Number INT) --Not sure why this works in a loop, but it does

     INSERT INTO @N

     SELECT Number

       FROM dbo.F_TABLE_NUMBER_RANGE(1,@DesiredRows)

    --===== Report the rowcount and duration in seconds

      PRINT STR(@@ROWCOUNT) + ' Rows Inserted '

          + CONVERT(CHAR(13),GETDATE()-@StartTime,114) + ' Duration F_TABLE_NUMBER_RANGE Method'

    --===== Delete rows from the table variable so as not to build up rows between tests

    --TRUNCATE TABLE @N --Doesn't work on table variables...

    --DROP TABLE @N     --Neither does this...

    DELETE @N           --But this does.

      PRINT REPLICATE('=',78)

    --================================================================================

    --===== End of test loop =========================================================

        SET @DesiredRows = @DesiredRows * 10

        END

    ... and here's the results it produced on my humble 1.8 Ghz 1 GB Ram SQL Server 2000 SP 4 Developer's Edition desktop box at home...

            10 Rows Inserted 00:00:00:000  Duration SELECT/INTO Method

            10 Rows Inserted 00:00:00:000  Duration F_TABLE_NUMBER_RANGE Method

    ==============================================================================

           100 Rows Inserted 00:00:00:000  Duration SELECT/INTO Method

           100 Rows Inserted 00:00:00:013  Duration F_TABLE_NUMBER_RANGE Method

    ==============================================================================

          1000 Rows Inserted 00:00:00:000  Duration SELECT/INTO Method

          1000 Rows Inserted 00:00:00:017  Duration F_TABLE_NUMBER_RANGE Method

    ==============================================================================

         10000 Rows Inserted 00:00:00:033  Duration SELECT/INTO Method

         10000 Rows Inserted 00:00:00:077  Duration F_TABLE_NUMBER_RANGE Method

    ==============================================================================

        100000 Rows Inserted 00:00:00:203  Duration SELECT/INTO Method

        100000 Rows Inserted 00:00:00:750  Duration F_TABLE_NUMBER_RANGE Method

    ==============================================================================

       1000000 Rows Inserted 00:00:02:000  Duration SELECT/INTO Method

       1000000 Rows Inserted 00:00:08:093  Duration F_TABLE_NUMBER_RANGE Method

    ==============================================================================

      10000000 Rows Inserted 00:00:20:253  Duration SELECT/INTO Method

      10000000 Rows Inserted 00:01:48:123  Duration F_TABLE_NUMBER_RANGE Method

    ==============================================================================

    --Jeff Moden


    RBAR is pronounced "ree-bar" and is a "Modenism" for Row-By-Agonizing-Row.
    First step towards the paradigm shift of writing Set Based code:
    ________Stop thinking about what you want to do to a ROW... think, instead, of what you want to do to a COLUMN.

    Change is inevitable... Change for the better is not.


    Helpful Links:
    How to post code problems
    How to Post Performance Problems
    Create a Tally Function (fnTally)