SQL2016 Upgrade to SQL2019 Long Running Query

Terry Kaczmarski 1 Reputation point
2020-11-23T20:46:27.513+00:00

Hello Everyone

We are converting several ETL processes from a windows 2012, SQL2016 environment to a windows 2019, SQL2019 environment. All is going well, except for one process. This process is running longer in SQL2019 then SQL2016.

The process performs an INSERT into A, select x from B, where x is a series of substring and case statements.

The source table basically contains 1 data field, 6,000 bytes long. The target table contains over 950 data columns, the largest in our ETL processes.

The source table contains 4.7 million rows and loads in 47 minutes, 100,000 rows per minute.

I split out 1 million rows for testing purposes, this runs in 10 minutes. Again, 100,000 rows per minute.

On my SQL2016, windows 2012 server, a full load runs in 12 - 14 minutes, while the 1 million sampling runs in 2 minutes.

For grins, I stalled SQL2016 on my ETL 2019 server and ran the same tests. Full load 7 minutes 14 seconds, whereas the 1 million sampling took 1 minute 32 seconds.

All three instances have a MAXDOP of 8 and a Cost Threshold For Parallelism (CTFP) of 50.

While the actual ETL process is procedure based, I pulled the insert code out and I'm running it in SSMS as t-sql commands.

I understand there are a lot of new "performance" improvements in SQL2019 and I've tried a lot of different combinations, so far, nothing has helped reduce the run times.

Some observations: A) reducing the target table to only 100 columns, 1 million rows loaded in 1 minute; 4.7 million loaded in 5 minutes. B) increasing the column count to 250 and loading 1 million rows took 6 minutes.
I cannot put my finger on it, but something around the substring/case function and how its interacting with SQL is causing me some grief.

So, I'm reaching out to SQL2019 guru's for advise and where to look, what to tune. Converting to SSMS at this time is not an option.

Your thoughts?

Developer technologies Transact-SQL
SQL Server Other
{count} votes

7 answers

Sort by: Most helpful
  1. Terry Kaczmarski 1 Reputation point
    2020-12-02T20:47:47.737+00:00

  2. David Browne 111 Reputation points Microsoft Employee
    2020-12-02T21:56:59.377+00:00

    I see no significant difference between SQL Server 2016 and 2019 with the following test script. Can you try, and perhaps modify it to reproduce the behavior you are seeing?

    use tempdb  
    select @@version   
    set nocount on  
    go  
      
    drop table if exists stg   
    drop table if exists foo  
      
    create table stg(id int identity primary key, importtext nvarchar(max))  
    insert into stg(importtext)   
    select replicate (cast('1' as nvarchar(max)), 500)  
    from sys.messages   
      
    go  
      
        SELECT   
           CHD_FullAccountNumber    =   substring(importtext,14,28)  
          ,CHD_DateInserted         =   getdate()  
          ,CHD_ProcessDate          =   getdate()--CONVERT(varchar(26),@HeaderDateTime)  
          ,CHD_System               =   substring(importtext,14,4)  
          ,CHD_Principal            =   substring(importtext,18,4)  
          ,CHD_Agent                =   substring(importtext,22,4)  
          ,CHD_AccountNumber        =   substring(importtext,26,16)  
          ,CHD_NEW_FILE_TYPE        =   substring(importtext,42,1)  
          ,CHD_RECORD_FORMAT        =   substring(importtext,43,2)  
          ,CHD_CUSTOMER_IDENT       =   CASE   
                                       WHEN substring(importtext,45,6) = ' ' THEN NULL  
                                          ELSE RTRIM(substring(importtext,45,6))  
                                        END    
          ,CHD_CLIENT_NUMBER        =   substring(importtext,51,4)  
          ,CHD_ACCOUNT_NO_EXPN      =   substring(importtext,55,3)  
          ,CHD_CIT_TOTL_CT          =   substring(importtext,58,5)  
          ,CHD_NO_DEL_ITEMS         =   substring(importtext,63,5)  
          ,CHD_NO_BEHAVIOR_SEGS     =   substring(importtext,68,5)  
          ,CHD_NO_CUSTOMER_SEGS     =   substring(importtext,73,5)  
          ,CHD_NO_HRSK_ACS_SEGS     =   substring(importtext,78,5)  
          ,CHD_FUTURE_SMALL_SEGS    =   CASE   
                                       WHEN substring(importtext,83,6) = ' ' THEN NULL  
                                          ELSE RTRIM(substring(importtext,83,6))  
                                        END  
          ,CHD_NO_SMALL_SEGS        =   substring(importtext,89,5)  
          ,CHD_NO_ALP_STAG_SEGS     =   substring(importtext,94,5)  
          ,CHD_NO_NEW_MISC2_SEGS    =   substring(importtext,99,7)  
          ,CHD_NO_NEW_MISC3_SEGS    =   substring(importtext,106,5)  
          ,CHD_NO_SLS_SYD_SEGS      =   substring(importtext,111,5)  
          ,CHD_FUTURE_LARGE_SEGS    =   substring(importtext,116,4)  
          ,CHD_NO_LARGE_SEGS        =   substring(importtext,120,5)  
          ,CHD_NO_SUPER_LARGE_SEGS  =   substring(importtext,125,5)  
          ,CHD_NO_FLAP_SEGS         =   substring(importtext,130,9)  
          ,CHD_NO_CHECKPOINTS       =   substring(importtext,139,9)  
          ,CHD_NO_TLP_BONUS_SEGS    =   substring(importtext,148,9)  
          ,CHD_NO_GLOBAL_NAME_CT    =   substring(importtext,157,5)  
          ,CHD_NO_GLOBAL_ADDRESS_CT =   substring(importtext,162,5)  
          ,CHD_NO_GLOBAL_PHONE_CT   =   substring(importtext,167,5)  
          ,CHD_NO_MMB_ITEM_CT       =   substring(importtext,172,5)  
          ,CHD_NO_PYST_ITEM_CT      =   substring(importtext,177,5)  
          ,CHD_NMBR_DSPT_ITEM_CT    =   substring(importtext,182,5)  
          ,CHD_AFK_ENTITY           =   substring(importtext,187,4)  
          ,CHD_AFK_CARD_NOCARD      =   substring(importtext,191,4)  
          ,CHD_AFK_BRANCH_PORTFO    =   substring(importtext,195,6)  
          ,CHD_AFK_OTHER1           =   substring(importtext,201,6)  
          ,CHD_EXTERNAL_STATUS      =   substring(importtext,207,1)  
          ,CHD_INTERNAL_STATUS      =   substring(importtext,208,1)  
          ,CHD_PREV_EXT_STATUS      =   substring(importtext,209,1)  
          ,CHD_CYCLE_CODE_99        =   substring(importtext,210,2)  
          ,CHD_DATE_LAST_NONMON     =  CASE WHEN substring(importtext,214,6) = 000000 THEN NULL  
                                            ELSE substring(importtext,214,6)          END  
          ,CHD_PREVIOUS_CYCLE_CODE_99   =   substring(importtext,220,2)  
          ,CHD_DLVR_PONT_NR         =   substring(importtext,222,9)  
          ,CHD_DLVR_BAR1_NR         =   substring(importtext,231,19)  
          ,CHD_DLVR_BAR2_NR         =   substring(importtext,250,19)  
          ,CHD_CHARGE_DDA_CODE      =   substring(importtext,269,1)  
          ,CHD_TRANSIT_ROUTING_NO   =   substring(importtext,270,10)  
          ,CHD_CHECKING_ACCT_NO     =   CASE   
                                       WHEN substring(importtext,280,17) = ' '     THEN NULL  
                                          ELSE RTRIM(substring(importtext,280,17))    END  
      into foo  
      from stg   
      where 1=0  
      
    go  
    set statistics time on  
    go  
      
        insert into foo with (tablock)  
        SELECT   
           CHD_FullAccountNumber    =   substring(importtext,14,28)  
          ,CHD_DateInserted         =   getdate()  
          ,CHD_ProcessDate          =   getdate()--CONVERT(varchar(26),@HeaderDateTime)  
          ,CHD_System               =   substring(importtext,14,4)  
          ,CHD_Principal            =   substring(importtext,18,4)  
          ,CHD_Agent                =   substring(importtext,22,4)  
          ,CHD_AccountNumber        =   substring(importtext,26,16)  
          ,CHD_NEW_FILE_TYPE        =   substring(importtext,42,1)  
          ,CHD_RECORD_FORMAT        =   substring(importtext,43,2)  
          ,CHD_CUSTOMER_IDENT       =   CASE   
                                       WHEN substring(importtext,45,6) = ' ' THEN NULL  
                                          ELSE RTRIM(substring(importtext,45,6))  
                                        END    
          ,CHD_CLIENT_NUMBER        =   substring(importtext,51,4)  
          ,CHD_ACCOUNT_NO_EXPN      =   substring(importtext,55,3)  
          ,CHD_CIT_TOTL_CT          =   substring(importtext,58,5)  
          ,CHD_NO_DEL_ITEMS         =   substring(importtext,63,5)  
          ,CHD_NO_BEHAVIOR_SEGS     =   substring(importtext,68,5)  
          ,CHD_NO_CUSTOMER_SEGS     =   substring(importtext,73,5)  
          ,CHD_NO_HRSK_ACS_SEGS     =   substring(importtext,78,5)  
          ,CHD_FUTURE_SMALL_SEGS    =   CASE   
                                       WHEN substring(importtext,83,6) = ' ' THEN NULL  
                                          ELSE RTRIM(substring(importtext,83,6))  
                                        END  
          ,CHD_NO_SMALL_SEGS        =   substring(importtext,89,5)  
          ,CHD_NO_ALP_STAG_SEGS     =   substring(importtext,94,5)  
          ,CHD_NO_NEW_MISC2_SEGS    =   substring(importtext,99,7)  
          ,CHD_NO_NEW_MISC3_SEGS    =   substring(importtext,106,5)  
          ,CHD_NO_SLS_SYD_SEGS      =   substring(importtext,111,5)  
          ,CHD_FUTURE_LARGE_SEGS    =   substring(importtext,116,4)  
          ,CHD_NO_LARGE_SEGS        =   substring(importtext,120,5)  
          ,CHD_NO_SUPER_LARGE_SEGS  =   substring(importtext,125,5)  
          ,CHD_NO_FLAP_SEGS         =   substring(importtext,130,9)  
          ,CHD_NO_CHECKPOINTS       =   substring(importtext,139,9)  
          ,CHD_NO_TLP_BONUS_SEGS    =   substring(importtext,148,9)  
          ,CHD_NO_GLOBAL_NAME_CT    =   substring(importtext,157,5)  
          ,CHD_NO_GLOBAL_ADDRESS_CT =   substring(importtext,162,5)  
          ,CHD_NO_GLOBAL_PHONE_CT   =   substring(importtext,167,5)  
          ,CHD_NO_MMB_ITEM_CT       =   substring(importtext,172,5)  
          ,CHD_NO_PYST_ITEM_CT      =   substring(importtext,177,5)  
          ,CHD_NMBR_DSPT_ITEM_CT    =   substring(importtext,182,5)  
          ,CHD_AFK_ENTITY           =   substring(importtext,187,4)  
          ,CHD_AFK_CARD_NOCARD      =   substring(importtext,191,4)  
          ,CHD_AFK_BRANCH_PORTFO    =   substring(importtext,195,6)  
          ,CHD_AFK_OTHER1           =   substring(importtext,201,6)  
          ,CHD_EXTERNAL_STATUS      =   substring(importtext,207,1)  
          ,CHD_INTERNAL_STATUS      =   substring(importtext,208,1)  
          ,CHD_PREV_EXT_STATUS      =   substring(importtext,209,1)  
          ,CHD_CYCLE_CODE_99        =   substring(importtext,210,2)  
          ,CHD_DATE_LAST_NONMON     =  CASE WHEN substring(importtext,214,6) = 000000 THEN NULL  
                                            ELSE substring(importtext,214,6)          END  
          ,CHD_PREVIOUS_CYCLE_CODE_99   =   substring(importtext,220,2)  
          ,CHD_DLVR_PONT_NR         =   substring(importtext,222,9)  
          ,CHD_DLVR_BAR1_NR         =   substring(importtext,231,19)  
          ,CHD_DLVR_BAR2_NR         =   substring(importtext,250,19)  
          ,CHD_CHARGE_DDA_CODE      =   substring(importtext,269,1)  
          ,CHD_TRANSIT_ROUTING_NO   =   substring(importtext,270,10)  
          ,CHD_CHECKING_ACCT_NO     =   CASE   
                                       WHEN substring(importtext,280,17) = ' '     THEN NULL  
                                          ELSE RTRIM(substring(importtext,280,17))    END  
      from stg   
      OPTION(maxdop 1)  
    go  
    set statistics time off  
    go  
    

    outputs

    Microsoft SQL Server 2016 (SP2) (KB4052908) - 13.0.5026.0 (X64)   
     Mar 18 2018 09:11:49   
     Copyright (c) Microsoft Corporation  
     Express Edition (64-bit) on Windows 10 Pro 10.0 <X64> (Build 19041: ) (Hypervisor)  
      
      
    SQL Server parse and compile time:   
       CPU time = 0 ms, elapsed time = 2 ms.  
      
     SQL Server Execution Times:  
       CPU time = 5469 ms,  elapsed time = 5473 ms.  
    SQL Server parse and compile time:   
       CPU time = 0 ms, elapsed time = 0 ms.  
    

    and

    Microsoft SQL Server 2019 (RTM-CU8) (KB4577194) - 15.0.4073.23 (X64)   
     Sep 23 2020 16:03:08   
     Copyright (C) 2019 Microsoft Corporation  
     Developer Edition (64-bit) on Windows 10 Pro 10.0 <X64> (Build 19041: ) (Hypervisor)  
      
      
    SQL Server parse and compile time:   
       CPU time = 0 ms, elapsed time = 2 ms.  
      
     SQL Server Execution Times:  
       CPU time = 5687 ms,  elapsed time = 5696 ms.  
    SQL Server parse and compile time:   
       CPU time = 0 ms, elapsed time = 0 ms.  
    
    
      
      
    

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.