• Phil Parkin - Thursday, October 12, 2017 9:04 AM

    Jeff Moden - Thursday, October 12, 2017 8:54 AM

    Except I goofed. :blush:  I posted before testing.  My method turns out to be the slowest between yours, Luis', and mine.


    --DROP TABLE #TestTable
    GO
    DECLARE  @StartDate DATE = '2000' --Inclusive
            ,@LimitDate DATE = '2017' --Exclusive
    ;
    DECLARE  @Days      INT  = DATEDIFF(dd,@StartDate,@LimitDate)
    ;
     SELECT TOP 1000000
            SomeDate = DATEADD(dd,ABS(CHECKSUM(NEWID())%@Days),@StartDate)
       INTO #TestTable
       FROM      sys.all_columns ac1
      CROSS JOIN sys.all_columns ac2
    ;
    GO
    --===== PRECAST METHOD
      PRINT '========== PRECAST Method ==============================================================='
        SET STATISTICS TIME ON;
    GO
    DECLARE  @RunDay  CHAR(2);
     SELECT @RunDay = RIGHT('0' + CAST(DAY(SomeDate) AS VARCHAR(2)), 2)
       FROM #TestTable;
    GO 3
        SET STATISTICS TIME OFF;
    --===== DATENAME METHOD
      PRINT '========== DATENAME Method ==============================================================='
        SET STATISTICS TIME ON;
    GO
    DECLARE  @RunDay  CHAR(2);
     SELECT @RunDay = RIGHT('0'+DATENAME(dd,SomeDate),2)
       FROM #TestTable;
    GO 3
        SET STATISTICS TIME OFF;
    --===== DATENAME METHOD
      PRINT '========== MATH OVERRUN Method ==============================================================='
        SET STATISTICS TIME ON;
    GO
    DECLARE  @RunDay  CHAR(2);
     SELECT @RunDay = RIGHT(100+DAY(SomeDate),2)
       FROM #TestTable;
    GO 3
        SET STATISTICS TIME OFF;

    That's not what I am seeing. On my system (2016 SP1), each method performs almost exactly the same.

    Here's the update code to include JustMarie's CASE method and Scott's CONVERT/CHAR(2) method.


    DROP TABLE #TestTable
    GO
    DECLARE  @StartDate DATE = '2000' --Inclusive
            ,@LimitDate DATE = '2017' --Exclusive
    ;
    DECLARE  @Days      INT  = DATEDIFF(dd,@StartDate,@LimitDate)
    ;
     SELECT TOP 1000000
            SomeDate = DATEADD(dd,ABS(CHECKSUM(NEWID())%@Days),@StartDate)
       INTO #TestTable
       FROM      sys.all_columns ac1
      CROSS JOIN sys.all_columns ac2
    ;
    --===== PRECAST METHOD
      PRINT '========== PRECAST Method ==============================================================='
        SET STATISTICS TIME ON;
    GO
    DECLARE  @RunDay  CHAR(2);
     SELECT @RunDay = RIGHT('0' + CAST(DAY(SomeDate) AS VARCHAR(2)), 2)
       FROM #TestTable;
    GO 3
        SET STATISTICS TIME OFF;
    --===== DATENAME METHOD
      PRINT '========== DATENAME Method ==============================================================='
        SET STATISTICS TIME ON;
    GO
    DECLARE  @RunDay  CHAR(2);
     SELECT @RunDay = RIGHT('0'+DATENAME(dd,SomeDate),2)
       FROM #TestTable;
    GO 3
        SET STATISTICS TIME OFF;
    --===== DATENAME METHOD
      PRINT '========== MATH OVERRUN Method ==============================================================='
        SET STATISTICS TIME ON;
    GO
    DECLARE  @RunDay  CHAR(2);
     SELECT @RunDay = RIGHT(100+DAY(SomeDate),2)
       FROM #TestTable;
    GO 3
        SET STATISTICS TIME OFF;
    --===== CASE METHOD
      PRINT '========== CASE Method ==============================================================='
        SET STATISTICS TIME ON;
    GO
    DECLARE  @RunDay  CHAR(2);
     SELECT @RunDay =   CASE
                        WHEN day(SomeDate) < 10
                        THEN '0' + CAST(DAY(SomeDate) AS VARCHAR(2))
                        ELSE cast(day(SomeDate) AS VARCHAR(2))
                        END
       FROM #TestTable;
    ;

    GO 3
        SET STATISTICS TIME OFF;
    --===== CONVERT CHAR(2) METHOD
      PRINT '========== CONVERT CHAR(2) Method ==============================================================='
        SET STATISTICS TIME ON;
    GO
    DECLARE  @RunDay  CHAR(2);
     SELECT @RunDay = CONVERT(CHAR(2), SomeDate, 1)
       FROM #TestTable;
    GO 3
        SET STATISTICS TIME OFF;

    And, yes, I agree.... they all run in almost the same time.  I know we're making million row runs here so a 10 ms difference doesn't matter much but I am seeing the MATH OVERRUN method the Luis posted consistently coming in at about 10ms faster than the rest (about 70ms faster than the CASE method) Are you seeing roughly the same thing?


    ========== PRECAST Method ===============================================================
    Beginning execution loop
    SQL Server parse and compile time:
       CPU time = 0 ms, elapsed time = 0 ms.

     SQL Server Execution Times:
       CPU time = 343 ms,  elapsed time = 333 ms.
    SQL Server parse and compile time:
       CPU time = 0 ms, elapsed time = 0 ms.

     SQL Server Execution Times:
       CPU time = 327 ms,  elapsed time = 331 ms.
    SQL Server parse and compile time:
       CPU time = 0 ms, elapsed time = 0 ms.

     SQL Server Execution Times:
       CPU time = 328 ms,  elapsed time = 329 ms.
    Batch execution completed 3 times.
    SQL Server parse and compile time:
       CPU time = 0 ms, elapsed time = 0 ms.
    ========== DATENAME Method ===============================================================
    Beginning execution loop
    SQL Server parse and compile time:
       CPU time = 0 ms, elapsed time = 0 ms.

     SQL Server Execution Times:
       CPU time = 343 ms,  elapsed time = 336 ms.
    SQL Server parse and compile time:
       CPU time = 0 ms, elapsed time = 0 ms.

     SQL Server Execution Times:
       CPU time = 328 ms,  elapsed time = 333 ms.
    SQL Server parse and compile time:
       CPU time = 0 ms, elapsed time = 0 ms.

     SQL Server Execution Times:
       CPU time = 343 ms,  elapsed time = 334 ms.
    Batch execution completed 3 times.
    SQL Server parse and compile time:
       CPU time = 0 ms, elapsed time = 0 ms.
    ========== MATH OVERRUN Method ===============================================================
    Beginning execution loop
    SQL Server parse and compile time:
       CPU time = 0 ms, elapsed time = 0 ms.

     SQL Server Execution Times:
       CPU time = 312 ms,  elapsed time = 321 ms.
    SQL Server parse and compile time:
       CPU time = 0 ms, elapsed time = 0 ms.

     SQL Server Execution Times:
       CPU time = 328 ms,  elapsed time = 320 ms.
    SQL Server parse and compile time:
       CPU time = 0 ms, elapsed time = 0 ms.

     SQL Server Execution Times:
       CPU time = 327 ms,  elapsed time = 321 ms.
    Batch execution completed 3 times.
    SQL Server parse and compile time:
       CPU time = 0 ms, elapsed time = 0 ms.
    ========== CASE Method ===============================================================
    Beginning execution loop
    SQL Server parse and compile time:
       CPU time = 0 ms, elapsed time = 0 ms.

     SQL Server Execution Times:
       CPU time = 390 ms,  elapsed time = 389 ms.
    SQL Server parse and compile time:
       CPU time = 0 ms, elapsed time = 0 ms.

     SQL Server Execution Times:
       CPU time = 375 ms,  elapsed time = 388 ms.
    SQL Server parse and compile time:
       CPU time = 0 ms, elapsed time = 0 ms.

     SQL Server Execution Times:
       CPU time = 390 ms,  elapsed time = 390 ms.
    Batch execution completed 3 times.
    SQL Server parse and compile time:
       CPU time = 0 ms, elapsed time = 0 ms.
    ========== CONVERT CHAR(2) Method ===============================================================
    Beginning execution loop
    SQL Server parse and compile time:
       CPU time = 0 ms, elapsed time = 0 ms.

     SQL Server Execution Times:
       CPU time = 343 ms,  elapsed time = 344 ms.
    SQL Server parse and compile time:
       CPU time = 0 ms, elapsed time = 0 ms.

     SQL Server Execution Times:
       CPU time = 343 ms,  elapsed time = 344 ms.
    SQL Server parse and compile time:
       CPU time = 0 ms, elapsed time = 0 ms.

     SQL Server Execution Times:
       CPU time = 374 ms,  elapsed time = 374 ms.
    Batch execution completed 3 times.
    SQL Server parse and compile time:
       CPU time = 0 ms, elapsed time = 0 ms.

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