Categories: ABAP StackPerformance

SAP Performance 101: Improving ABAP Code

A few days ago I received the SAP Community Voice Newsletter in my email. I recommend you signing in SAP newsletters since they have really interesting articles about different topics. Anyway I found in the newsletter a really interesting article about improving ABAP code performance that I totally recommend to read:

How To Improve Your ABAP Code Performance

I want to give you a perfect example of how a bad ABAP code can completely destroy the performance of a program.

The problem

End-user complains about the overall performance of the system. As usual after checking with the user the performance issue is located on a few Z programs that he uses almost everyday.

As usual the system’s information is the following:

  • SAP ERP 6.00 EHP8.
  • MS SQL Server 2012 running on its own VM.
  • Windows Server 2012 R2.
  • Kernel 749 Patch 413.
  • Central Instance + Dialog Instance. Both running on individual VMs.

The investigation

First of all I executed the transaction and I notice a high execution times in all the executions. Just to be clear a high execution time not always means a performance issue. As I explained before the perception of the user related to the execution time cannot be taken as an indicator for a performance issue on a SAP system. Users are human beings (most of the time) and nowadays humans are impatient…

Let’s start doing a performance trace of the program using ST12 transaction. I copied part of the data in the screenshot:

ST12 trace of Z program

What is interesting here is that almost the whole execution time goes in the ABAP side. There is almost no database time which is usually strange. Of the calls side we can see that 2 reads to tables are consuming 66% and 33% of the total time. In this case it is clear that we have to take a look to both READ TABLE since there is something strange on them…

Checking the ABAP code

So I checked the ABAP code and I found the following READ TABLE on the code. The first thing that I saw was the SELECT INTO TABLE:

SELECT * FROM ztable INTO TABLE gt_alis_imputac.

Seeing this we already know that the SELECT * is not the best way to perform a SELECT. As the article stated the SELECT should be limited to the data we want/need because a SELECT * is inefficient. Anyway the performance issue is not in this SELECT since there was no execution time registered in the database side. I kept checking the code and I found a SORT for the gt_alis_imputac table:

  SORT gt_alis_imputac BY bukrs
                          ...

So this part of code should improve the performance of the program for the following READ TABLE done using this table. The READ table are the following ones:

READ TABLE gt_alis_imputac TRANSPORTING NO FIELDS 
WITH KEY bukrs      ...
READ TABLE gt_alis_imputac TRANSPORTING NO FIELDS
WITH KEY bukrs      ...

So basically what happens here is that since the gt_alis_imputac table is defined as standard table then the read statements perform a linear seach til the end of the table. It really doesn’t matter if the person who created the program wrote a SORT before the READ TABLE, it just keep searching through the whole table.

Even worst, during the LOOP where the READ TABLE are performed the code modifies the gt_alis_imputac adding new records using an APPEND. This will cause that the sort order is destroyed after the first insert and impacting in the performance.

Doing things the right way

One easy action that we can do to improve this code is to use a BINARY SEARCH in each READ. The READ TABLE code would be something similar to this:

READ TABLE gt_alis_imputac TRANSPORTING NO FIELDS 
WITH KEY bukrs      ...
BINARY SEARCH.

Even better, if we declare the gt_alis_imputac as a SORTED TABLE we don’t need to perform a SORT of the table and we can skip the BINARY SEARCH. The READ statement automatically perform a binary search for sorted tables. The only problem will be using the same fields in the WITH KEY condition that the components of the table gt_alis_imputac.

Binary search is  faster and more efficient than linear search. If we don’t write BINARY SEARCH then we are using the linear search which search one by one record from the table.  For small tables is a good idea use a linear search since the performance won’t be impacted. But when we have big tables like this case the best practice is to use a BINARY SEARCH. This way what would happen is that the table will be divided in two equal parts. The search will check each part and decide in which of the part the element will be. Again, it will divide that part in two parts and do the same. This image explains it perfectly:

Binary Search Vs Linear Search

Notice the number of steps between a binary search and a linear search in a sorted table. About the adding new registers in a SORTED TABLE, if you use INSERT instead APPEND then the new registers will be added in the correct position.

Performance after modifying the code

I performed a new ST12 trace after improving the code:

ST12 trace of Z program after improving code

Several things to remark here:

  • The total execution time went from 2.947 seconds to 2,7 seconds as result of the changes we performed.
  • The top calls right now are the 2 SELECT * that I mentioned before. We can improve the execution time using specific fields instead * in the SELECT.
  • The READ TABLE went from 66% and 33% of the total execution time to 8,7% and 7,9%. Most noteworthy the execution time for those calls went from 1.900 and 1.002 seconds to 0,2 seconds.

Conclussions

I think you get the idea of how a bad coding can impact greatly on the performance of the program. In this case the solution was really easy to implement and it didn’t’t take longer than 5 minutes.

Best coding practices and recommendations are created for a reason and it is quite common to ignore them. If you are a programmer please spend time improving your code. I know it is hard and you probably had better things to do but I promise it is completely worth it.

Mike

Recent Posts

DevOps, Infrastructure as Code and SAP

I hope you all survived the log4j Apocalypse and Christmas, hopefully you had a great…

2 years ago

Log4Shell Critical vulnerability

I know it is being a while since I posted the last time. So far…

2 years ago

Adobe Acrobat Reader Security Update causing issues with SAPGUI

UPDATE 11/25/2020 Adobe released a new patch that solves the issue a few days ago:…

3 years ago

SAP GUI 7.70 Preview: They will know me as Quartz

Good news for you fanatics of SAP GUI! SAP will release SAP GUI 7.70 in…

4 years ago

Preparing the SAP Cloud Consultant Interview

Quick update since I don't have a lot of time lately. During my 2019 job…

4 years ago

It's the final countdown (2019 Edition)

It's been a while since the last time I wrote an entry in my blog.…

4 years ago