Application Development and Automation Discussions
Join the discussions or start your own on all things application development, including tools and APIs, programming models, and keeping your skills sharp.
cancel
Showing results for 
Search instead for 
Did you mean: 
Read only

Best performance tuning ways while using BADIs

ishwarya_doss
Participant
0 Likes
3,651

Hi Experts,

Sometimes a select statement written inside a BADI method can be triggered for all the records in loop which may affect the performance. Could you pls share the best possible ways to avoid identical selects in such cases?

For example - using static atts of a class and where can it be used?

1 ACCEPTED SOLUTION
Read only

MateuszAdamus
Active Contributor
3,461

Hello anabaperlife

First check if the table itself isn't buffered. If it is, then buffering in BADI does not make much sense.

Later, if the table isn't buffer, a simple buffering using a static internal table would be one way to go. Check the internal table first, see if there is a record for given conditions, read DB only if there isn't, save the read record to the internal table for later use.

For more complex solution, a Singleton pattern could be used. You could create a Singleton implementation of a buffering object, which could store read records and allow access to them from different places in your logic (this part is same as in the above paragraph).

Kind regards,
Mateusz

Hi Experts,

Sometimes a select statement written inside a BADI method can be triggered for all the records in loop which may affect the performance. Could you pls share the best possible ways to avoid identical selects in such cases?

For example - using static atts of a class and where can it be used?

12 REPLIES 12
Read only

MateuszAdamus
Active Contributor
3,462

Hello anabaperlife

First check if the table itself isn't buffered. If it is, then buffering in BADI does not make much sense.

Later, if the table isn't buffer, a simple buffering using a static internal table would be one way to go. Check the internal table first, see if there is a record for given conditions, read DB only if there isn't, save the read record to the internal table for later use.

For more complex solution, a Singleton pattern could be used. You could create a Singleton implementation of a buffering object, which could store read records and allow access to them from different places in your logic (this part is same as in the above paragraph).

Kind regards,
Mateusz
Read only

matt
Active Contributor
3,461

Many people don't seem to realise that you can add your attributes and (private) methods to your BADI implementation, which is what is needed to effectuate this solution.

A couple of other points:

  • When testing, it turns out that buffering a table in an internal table is faster than relying on table buffering.
  • If the table or data required from it is a small enough set, it can make sense to read the entire table into an internal table in the CLASS_CONSTRUCTOR. Make sure you give it HASHED with a suitable key.
Read only

3,461

Hello anabaperlife

If your BADI is controlled by a TVARVC and other table records, then read these records during the first run of the BADI into internal tables and then check these internal tables, instead of making a DB select each time.

As Matthew pointed out, if the data required is small enough, it's better to read all at once and then read it from memory, than read it record by record from a DB. Reading from a sorted or hashed table is much faster than reading from a database.

Kind regards,
Mateusz
Read only

0 Likes
3,461

Thanks a lot for all your answers.

It would be more helpful if there is any simple example to get the concept completely. Thanks in advance!

Read only

3,461

Hi Meera

BADI implementation is just an ordinary class with specific interfaces. You can edit this class in SE24 transaction.

After you've created your BADI implementation go to SE24 transaction and enter the class name (you can find the class' name in the details of your BADI implementation). Enter in edit mode. In the class, on Attributes tab, add a new static attribute. Its visibility can be private. The attribute should be an internal table (sorted or hashed) with line type same as the table you want to read data from (you might need to create this type in the class Types tab, if not found in ABAP dictionary). In the method with your BADI's logic add code:

READ TABLE at_buffer REFERENCE INTO DATA(ld_buffer)
  WITH TABLE KEY key_field_1 = value_1 key_field_2 = value_2 key_field_2 = value_2.
IF sy-subrce <> 0. " record not buffered yet
  CREATE DATA ld_buffer.
  SELECT * " or specific fields, depends on you
   FROM table_name
   WHERE key_field_1 = value_1
     AND key_field_2 = value_2
     AND key_field_n = value_n
   INTO @ld_buffer->*.

   " fill-in key fields in case no DB record found
   " otherwise it would try to read the record from DB multiple times
   ld_buffer->key_field_1 = value_1.
   ld_buffer->key_field_2 = value_2.
   ld_buffer->key_field_n = value_n.
   INSERT ld_buffer->* INTO TABLE at_buffer.
ENDIF.

KEY_FIELD_1, KEY_FIELD_2 and so on depend on your configuration table structure and conditions you use for driving the BADI. So do the VALUE_1, VALUE_2 and other condition values.

As Matthew mentioned, if there isn't a lot of data in the table that drives the BADI you can pre-select the records in the CLASS_CONSTRUCTOR method.

METHOD class_constructor. " has to be created in SE24 with the Class Constructor button
  SELECT * " or specific field, depends on you
    FROM table_name
    INTO TABLE @at_buffer.
ENDMETHOD.

You can have multiple AT_BUFFER attributes in your class, each for a separate configuration table.

Kind regards,
Mateusz
Read only

gasparerdelyi
Product and Topic Expert
Product and Topic Expert
0 Likes
3,461

In certain cases, a mass pre-fill of the static buffer can bring further performance gain (if there are still lots of non-identical queries after buffering).
In order to implement a mass pre-fill (I guess the CLASS_CONSTRUCTOR approach is about the same), there needs to be another BAdI method call or at least a chance to implement an implicit enhancement at the right place.
Do not be afraid to ask for a BAdI method to be added in an incident if it is missing and there is still a performance issue after getting rid of the identicals.

Read only

Sandra_Rossi
Active Contributor
3,461

"Static" is needed only if the BAdI instance is different at each call... Maybe you could explain your actual case?

Read only

former_member1716
Active Contributor
3,461

anabaperlife,

You can try restricting your code such that it triggers only for your necessary condition. But it's again depends on your business scenario. We suggest better solution based on your input.

Read only

ishwarya_doss
Participant
0 Likes
3,461

The code is restricted based on TVARVC which is a buffered table and another custom table. BADI gets called for each record in the loop and hence identical select % is huge. This is for FILL ADD COLUMNS In MD04.

Read only

Sandra_Rossi
Active Contributor
3,461

Can't you use an instance attribute or static attribute, and do SELECT only once with method CONSTRUCTOR or CLASS_CONSTRUCTOR as suggested by Matthew.

Read only

ishwarya_doss
Participant
0 Likes
3,461

Thanks a lot, Mathew. Yes, i would like to know more about adding private methods to BADI implementation.. Please share if there are any documents to refer.

Read only

ishwarya_doss
Participant
0 Likes
3,461

Thanks Matthew Billingham, Mateusz Adamus and Sandra Rossi. Your suggestions helped. Closing this thread