• Nice article and great explanation in the article... too bad they didn't actually test it for performance... 😉 Both of the following UDF's render identical execution plans and they both take turns winning on my desktop. That also means that compared to the inline code, they both make some nasty sucking sounds. 😛 I got the function code below from the article.

    [font="Courier New"]


    --===== Create a scalar function with SchemaBinding 

     CREATE FUNCTION dbo.ComputeNumSB(@i INT)

    RETURNS INT

       WITH SCHEMABINDING

      BEGIN

            RETURN @i * 2 + 50

        END

    GO

    --===== Create a scalar function without SchemaBinding

     CREATE FUNCTION dbo.ComputeNum(@i INT)

    RETURNS INT

      BEGIN

            RETURN @i * 2 + 50

        END

    GO

    --===== Create and populate the Tally table on the fly

     SELECT TOP 1000000 --equates to more than 30 years of dates

            IDENTITY(INT,1,1) AS N

       INTO dbo.Tally

       FROM Master.dbo.SysColumns sc1,

            Master.dbo.SysColumns sc2

    --===== Add a Primary Key to maximize performance

      ALTER TABLE dbo.Tally

        ADD CONSTRAINT PK_Tally_N 

            PRIMARY KEY CLUSTERED (N) WITH FILLFACTOR = 100

    --===== Allow the general public to use it

      GRANT SELECT ON dbo.Tally TO PUBLIC

    GO

    --===== Test more than once... the functions take turns winning.

         -- The inline code ALWAYS blows the functions away.

    DECLARE @BitBucket INT

    DECLARE @TestSize  INT

     SELECT @TestSize = 100000

    SET STATISTICS TIME ON

     SELECT @BitBucket = dbo.ComputeNumSB(t.N)

       FROM dbo.Tally t

      WHERE t.N <= @TestSize

     SELECT @BitBucket = dbo.ComputeNum(t.N)

       FROM dbo.Tally t

      WHERE t.N <= @TestSize

     SELECT @BitBucket = t.N * 2 + 50

       FROM dbo.Tally t

      WHERE t.N <= @TestSize

    SET STATISTICS TIME OFF

    PRINT REPLICATE('=',80)

    GO 6


    [/font]

    For those that don't know what a Tally table is, now would be a good time to learn. Please see the following article...

    http://www.sqlservercentral.com/articles/T-SQL/62867/

    I agree with most of the other's said here... a UDF is probably not the way to go here. An aux table or a bit of inline code is the way to go. Here's the run results from the code above...

    [font="Courier New"]Beginning execution loop

    SQL Server Execution Times:

    CPU time = 8625 ms, elapsed time = 16175 ms.

    SQL Server Execution Times:

    CPU time = 8922 ms, elapsed time = 16226 ms.

    SQL Server Execution Times:

    CPU time = 78 ms, elapsed time = 78 ms.

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

    SQL Server Execution Times:

    CPU time = 8704 ms, elapsed time = 16103 ms.

    SQL Server Execution Times:

    CPU time = 8875 ms, elapsed time = 16358 ms.

    SQL Server Execution Times:

    CPU time = 78 ms, elapsed time = 76 ms.

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

    SQL Server Execution Times:

    CPU time = 8203 ms, elapsed time = 16051 ms.

    SQL Server Execution Times:

    CPU time = 8406 ms, elapsed time = 16075 ms.

    SQL Server Execution Times:

    CPU time = 78 ms, elapsed time = 94 ms.

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

    SQL Server Execution Times:

    CPU time = 8922 ms, elapsed time = 15994 ms.

    SQL Server Execution Times:

    CPU time = 8922 ms, elapsed time = 19858 ms.

    SQL Server Execution Times:

    CPU time = 78 ms, elapsed time = 81 ms.

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

    SQL Server Execution Times:

    CPU time = 8203 ms, elapsed time = 17882 ms.

    SQL Server Execution Times:

    CPU time = 8844 ms, elapsed time = 19245 ms.

    SQL Server Execution Times:

    CPU time = 94 ms, elapsed time = 86 ms.

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

    SQL Server Execution Times:

    CPU time = 8297 ms, elapsed time = 16888 ms.

    SQL Server Execution Times:

    CPU time = 8656 ms, elapsed time = 18983 ms.

    SQL Server Execution Times:

    CPU time = 78 ms, elapsed time = 79 ms.

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

    Batch execution completed 6 times.

    [/font]

    --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)