ABAP Runtime Analysis of Transformations & DTPs
Introduction
We develop various ABAP Programs, Customized T-codes and Function Modules in our projects as per our requirements. To fine tune our developments, we have to check “What are the Runtimes of our ABAP Programs, Customized T-codes and Customized Function Modules?”
SAP has given us a nice t-code SE30 for this purpose. You can check the runtimes of Standard (ABAP programs, T-codes and FMs)
This blog is not to test the data volume handling through transformation and DTPs. Because data volume is not fixed, today you do some analysis by based on some amount of volume and you arrive some figures in the statistics from SE30. But the data load may increase/decrease.in future. So then today’s analysis will be invalidated. That’s exactly I have proposed to test the ABAP coding part only before loading data through transformations/DTPs.
I am going to demonstrate How to do Runtime Analysis of Transformations and DTPs.. in this blog.
Step 1: Go to the Transformation —> Extras from the top menu —> Display Generated Program, then you see the screen like below.
Step 2 : Copy the technical name(whole string) of the generated report
Step 3 : Go to SE30 t-code and paste it in Program text box and press execute like below
This will calculate Runtimes in three categories. You can check them by pressing Evaluate button in above screen shot.
Finally you can make a note of various Runtimes by observing the below screen.
Result : The above Program has spent majority of time in ABAP(Presentation), 11.5% at Database level(Datsbase Systems like MSSQL, Oracle etc) and 7.7% at System level(Application)
Similarly, you can copy the string from DTP–>Extras–>Generated Program Filter and check the runtimes by following above steps
Note : Suppose you are analyzing some FM / t-code, when you press Execute as per Step 3, you will literally get into the execution of that FM / t-code and you see the result–>Then you need to press Back button on top to reach SE30 screen –>You will see Runtime Analysis of so and so FM / t-code has been finished on the Status bar at bottom of the screen. Finally you can click on Evaluation button to see various runtimes
Nice blog to analyze the performance of t/fs and DTP. Thanks for making such nice article.
Thank u raman..
Really good document..ll be helpful for analyzing run time analysis.
Regards,
AL
Thank you Anshu...
Good blog suman.
Thank you Ravi...
Hi Suman,
Thanks to you. I learnt something new today. Looks like BW has a lot of 'easter eggs' like these waiting to be discovered 🙂
Nice document.
Regards,
Benedict
Yeah, BW is an ocean. There will be always something left even after working so much..Thanks
Thanks Suman for sharing this Amazing blog..
Regards,
Abdullah
Thank you abdullah..
Thanks Suman
Really a good document 🙂
Purushotham.
Thank you purushotham
Hi Suman,
Sorry but I think that this way does not work at all..
If you look at this generated program, you will see that only have methods and forms, when you try to execute in SE38, for example, the abap code will not be called.. using the transaction SE30 in this way will have the same effect
Hi Paulo,
This is an auto generated program by the system. You cannot assess individual routines and field level routines individually. There is no privilege available as of now. The only way is to take the auto generated program and do analysis in SE30 as I mentioned. I have tested almost all of my transformations and DTPs in this fashion. I observed different variations in "Evaluation tab". This gave me an idea on How best are my Transformations and DTPs in terms of performance. You cannot execute this generated program in SE38 as this is not executable program, just a generated program.
You can check the runtimes(processings of all datapackages) of DTPs in DTP monitor itself. Here in my blog, I talk about Runtime Anlaysis in three places(ABAP,Database and System). Please try to understand the difference between the two.
Please test some of your Transformations and DTPs by using my blog to understand the reality.
Regards,
Suman
Hi Suman,
When I talked about using SE38 my intention was to say that using SE30 will not call any routine of the generated program too, I mean, in this approach seems that the custom code (start or end routine in the transformation for example) will not be evaluated in the graph.
Regards,
Paulo.
Hi Paul,
I have analyzed my Transformation Generated Program thoroughly. It considers all routines which are part of the transformation like Start/End routines and field routines too.
I am 100% correct. If you want, you can analyze your generated program, to see all the logics of your routines are considered while evaluating in Graphs. You can debug in Se38. I am just wondering on ,How couldn't you see the routine logics in the generated program in SE38? I am able to view them. Just look at your generated program to observe all your field routines ans start/end routines will be considered.
I repeat the graph does not give dummy figure. It evaluates all routines inside and finally give you the graph.
I have tested everything before making the blog.
Regards,
Suman
Hi Suman,
Yeah I am able to see routine logic in the generated program, that is not the point.
Maybe I am facing a different behavior in SE30, but in the graph screen, when I press the button Hit List (F5), it shows me something like that:
Call
Runtime analysis
Submit Report GP33D5W03QZJP0B164OBEY72NKY
Program GP33D5W03QZJP0B164OBEY72NKY
Load Report GP33D5W03QZJP0B164OBEY72NKY
Event SYSTEM-EXIT
Perform not found BEFORE_EVENT
This screen shows the trace of the runtime analysis, including the gross time that is used in the graph.
It is possible to see more detailed information selecting all options in Display Filter (Shift+F2)
In my test, this trace does not show any perform, call function or call method that exists in start/end/field routines.
I am not saying that you are wrong, maybe in your tests the custom code is in the Hit List, I believe that this post can be very helpful for many people, but I get a different result and I was trying to figure out why.
Regards,
Paulo.
Hi Paul,
I am able to see "Cal Method" and "Call Function" in my Hit list. Can you try with any other transformations? This is something strange in your case..
Thanks to start working on my doc.
Regards,
Suman
Hi Suman,
Can you show us your "Hit list" please?
What happens when you run the same transformation program twice? the result changes?
Regards,
Paulo.
HI Paulo,
I am not in front of PC now. I cannot show you my "Hit List". Please read my whole blog once again and try with User/service if you want to test data. Otherwise, just try with execute.
Regards,
Suman
Hi Paulo,
While making the blog, i have tested at least 10 -15 transformations/DTPs in my system. I got different Graphs for all. This proves that it does not give you dummy graphs. SE30 is a standard t-code which can be used for runtime analysis. I don't know what's wrong with your analysis? If you think it is a trash, it is up to you. You may simply ignore the blog and try to find out other way and share with me. Then, i will discard this blog and follow yours. No hurt feelings for me. I am open..Please read a new paragraph which i have added.
Regards,
Suman
Really a good blog suman.
Thank you Devi
Hi Suman,
Its really a good way to find about the runtimes. However, as per Paulo, is it true that the generated programs of transformations, when evaluated, will not consider routines involved in it?
Please do update me whether it also consider the runtime of routines involved when displaying the results for the transformations.
Thanks & regards,
Mohammed Naveed.
Hi Mohammed,
I have analyzed my Transformation Generated Program thoroughly. It will consider all routines which are part of the transformation like Start/End routines and field routines too.
I am 100% correct. If you want, you can analyze your generated program, to see all the logics of your routines are considered while evaluating in Graphs.
Regards,
Suman
Hi Suman,
Thats awesome. I really appreciate your work and analysis.
Thank you for clearing this confusion.
Regards,
Mohammed.
Thank you mohammed..
Hi Suman,
Nice document for ABAP Code runtime Analysis..
Thanks
Arun
Thank you Arun for your words..
Suman,
Really nice one and thanks for sharing 🙂
Thanks,
Phani.
Very Useful...Many Thanks.
Best Regards,
Naresh K.
Thank you Naresh and U r welcome.
Really helpfull Document... I missed this doc...
Good job Suman..
Cheers
KP
Hey Prashanth,
Thank you so much for your great compliments.
Regards,
Suman
Suman Chakravarthy K Useful one .. thanks .. ll bookmark this 😀
HI Nethaji,
Thank you so much for reading my blog.
I learnt something new today.
Thanks a lot....
Hi Prabhit,
Glad to know that 🙂
Hi Suman,
Thanks for sharing.
I have a doubt how does it claculates the runtime. Does it executes the DTP when you give the generated program name for tranformation over there because transformation would only be read when DTP is ran.
I have not tested the same before putting this questions. May be i would do that later.
Thanks
After every creation of Trans/DTP, the system it self creates a generated program after activating them. This run time is all about ABAP, database and System as per your design. This will not run the DTP while testing this. This will indicate you where all(ABAP, Datbase and System) levels, the more time your object(Trans/DTP) spends..Before finalizing your Trans and DTP routines, it's advisable to test as per the blog.
Hi Suman,
Thanks.
I understands that generated program would be created automatically once trans/dtp are activated.I need to know how will it tell without running the DTP the areas which needs improvement if any.Is it going to test based upon previous DTP logs may be from stats.
Although i would test the same.
Regards
Kamal
This is to test the Routines which are used in Transformation/DTP. It will not check from statistics. You are getting diverted.
Hi Suman,
I have just tested it in my system. Its like providing information using which one can check analyze various routines used in the transformation. More the time in database worse the performance.
Got it thanks for shaing.
Regards
Kamal
Now you understood it clearly. 🙂
Hi Suman,
the described procedure to analyse the runtime of a BW transformation or DTP is not working - at least on BW 730. The reason is, that if you execute the generated program of the transformation in SM30, the transformation is run without any records. The program does not select the data on its own, but needs a dtp to provide the records for the transformation.
To get the SM30 work with a dtp/transformation you have to use the "Schedule for User/Service" option.
Best regards,
Daniel
Hi Daniel,
You have misunderstood the blog. My procedure is to find out the runtimes in three categories before loading data. This procedure is just to test the ABAP codes performance but not to test the data volume. Your point has already been discussed in other above comments by others.
I am ware that "Schedule for User/Service" is for your purpose. Please review your comments once again.
Regards,
Suman
Hi All,
I have added a new paragraph in highlighted black color. You may go through to get some idea.
Regards,
Suman
Hi Suman,
if you run the generated program in SE30 directly the coding of the transformation (start-, end-routine, etc.) is not executed. So, the figures produced by SE30 are quite useless.
I have tested the procedure with several transformations and I always got the same result. Actually I should have got different results, depending on the transformation routines.
Best regards,
Daniel
OK. It's not helpful to you. Please ignore the blog. I repeat, i have tested at least 10-15 cases, i got different results. Only then, i made this blog. Thanks for your straight forward review.
Really useful information & thanks for the information Suman Chakravarthy K
Hi Hemanth,
Thanks for the feedback 🙂
Thanks alot suman..
Nice help suman..... 🙂
Regards,
SM
Good Document !!
Nice information suman 🙂
Hi Suman,
Really You Rocks.,.,.,
the presentation is simply superb...
Regards,
J.sakthikumar
Hi Suman,
Thanks for sharing very good document.
I checked one of the transformations. Data load to DSO is taking 50 minutes to load 1.5 lakhs records. So i checked in SM30 and please find the below screenshot. I just want to reduce the data load time. As of now, from the graph, it is showing 80% in data base level. Please suggest how to reduce the loading time.
Thanks for writing to me. Unless we see your code, we cannot really suggest the best methods. Please post it..
Have you used any semantic groups in DTP?
Hi Suman,
Sorry for the late reply. Herewith I am attaching the code written in the End Routine. The above snapshot belongs to this Code. Please have a look.
*$*$ begin of global - insert your declaration only below this line *-*
... "insert your code here
TYPES:
BEGIN OF ty_stat,
/bic/zemplye TYPE /bic/oizemplye,
/bic/zcustsls TYPE /bic/oizcustsls,
/bic/zotlkvgr1 TYPE /bic/oizotlkvgr1,
/bic/zacustsls TYPE /bic/oizacustsls,
/bic/zicustsls TYPE /bic/oizicustsls,
/bic/zsdate TYPE dats,
/bic/zedate TYPE dats,
END OF ty_stat.
DATA:
it_stat TYPE TABLE OF ty_stat,
it_stat_dup TYPE TABLE OF ty_stat,
wa_stat TYPE ty_stat,
it_stat2 TYPE TABLE OF ty_stat,
wa_stat2 TYPE ty_stat.
*$*$ end of global - insert your declaration only before this line *-*
METHODS
new_record__end_routine
IMPORTING
source_segid type rstran_segid
source_record type sytabix
EXPORTING
record_new type sytabix.
METHODS
end_routine
IMPORTING
request type rsrequest
datapackid type rsdatapid
EXPORTING
monitor type rstr_ty_t_monitors
CHANGING
RESULT_PACKAGE type _ty_t_TG_1
RAISING
cx_rsrout_abort.
METHODS
inverse_end_routine
IMPORTING
i_th_fields_outbound TYPE rstran_t_field_inv
i_r_selset_outbound TYPE REF TO cl_rsmds_set
i_is_main_selection TYPE rs_bool
i_r_selset_outbound_complete TYPE REF TO cl_rsmds_set
i_r_universe_inbound TYPE REF TO cl_rsmds_universe
CHANGING
c_th_fields_inbound TYPE rstran_t_field_inv
c_r_selset_inbound TYPE REF TO cl_rsmds_set
c_exact TYPE rs_bool.
ENDCLASS. "routine DEFINITION
*$*$ begin of 2nd part global - insert your code only below this line *
... "insert your code here
*$*$ end of 2nd part global - insert your code only before this line *
*---------------------------------------------------------------------*
* CLASS routine IMPLEMENTATION
*---------------------------------------------------------------------*
*
*---------------------------------------------------------------------*
CLASS lcl_transform IMPLEMENTATION.
*----------------------------------------------------------------------*
* Method end_routine
*----------------------------------------------------------------------*
* Calculation of result package via end routine
* Note: Update of target fields depends on rule assignment in
* transformation editor. Only fields that have a rule assigned,
* are updated to the data target.
*----------------------------------------------------------------------*
* <-> result package
*----------------------------------------------------------------------*
METHOD end_routine.
*=== Segments ===
FIELD-SYMBOLS:
<RESULT_FIELDS> TYPE _ty_s_TG_1.
DATA:
MONITOR_REC TYPE rstmonitor.
*$*$ begin of routine - insert your code only below this line *-*
... "insert your code here
DATA:
result1 TYPE TABLE OF _ty_s_tg_1 ,
v_salesman TYPE /bic/oizemplye,
v_month(6) TYPE c,
st_month(6) TYPE c,
en_month(6) TYPE c,
v_count(12) TYPE c VALUE 0.
result1[] = RESULT_PACKAGE[].
TYPES : BEGIN OF ty_outlet,
lv_outlet TYPE /bic/oizcust_sal,
lv_outtype TYPE /bic/oiyotlt_typ,
lv_outsubtype TYPE /bic/oiygrp_otlt,
END OF ty_outlet.
DATA : it_outlet TYPE STANDARD TABLE OF ty_outlet,
wa_outlet TYPE ty_outlet.
BREAK-POINT.
APPEND LINES OF it_stat2 TO it_stat_dup.
SORT it_stat_dup BY /bic/zcustsls.
DELETE ADJACENT DUPLICATES FROM it_stat_dup COMPARING /bic/zcustsls.
IF it_stat_dup IS NOT INITIAL.
SELECT
/bic/zcust_sal
/bic/yotlt_typ
/bic/ygrp_otlt
FROM /bic/pzcust_sal
INTO TABLE it_outlet
FOR ALL ENTRIES IN it_stat_dup
WHERE /bic/zcust_sal = it_stat_dup-/bic/zcustsls.
IF sy-subrc = 0.
SORT it_outlet BY lv_outlet.
ENDIF.
ENDIF.
*-- fill table "MONITOR" with values of structure "MONITOR_REC"
*- to make monitor entries
... "to cancel the update process
* raise exception type CX_RSROUT_ABORT.
LOOP AT RESULT_PACKAGE ASSIGNING <result_fields>.
CLEAR wa_stat2.
IF v_salesman = <result_fields>-/bic/zemplye
AND v_month = <result_fields>-calmonth.
CONTINUE.
ELSE.
CLEAR v_salesman . CLEAR v_month.
v_salesman = <result_fields>-/bic/zemplye.
v_month = <result_fields>-calmonth.
LOOP AT it_stat2 INTO wa_stat2
WHERE /bic/zemplye = <result_fields>-/bic/zemplye
AND /bic/zcustsls NE <result_fields>-/bic/zcustsls.
* st_month = wa_stat2-/bic/zsdate+0(6).
* en_month = wa_stat2-/bic/zedate+0(6).
* IF v_month GE st_month and v_month LE en_month .
<result_fields>-/bic/zcustsls = wa_stat2-/bic/zcustsls.
CLEAR : wa_outlet.
READ TABLE it_outlet INTO wa_outlet
WITH KEY lv_outlet = wa_stat2-/bic/zcustsls
BINARY SEARCH.
IF sy-subrc = 0.
<result_fields>-/bic/zouttyp = wa_outlet-lv_outtype.
if wa_outlet-lv_Outsubtype is not INITIAL.
<result_fields>-/BIC/ZOUTGRP = wa_outlet-lv_Outsubtype.
endif.
IF wa_stat2-/bic/zotlkvgr1 NE 2 .
<result_fields>-/bic/zspjpstat = 'N'.
<result_fields>-/bic/zicustsls = wa_stat2-/bic/zcustsls.
"<RESULT_FIELDS>-/BIC/ZMATERIAL = ' '.
<result_fields>-/bic/znetsle = ' '.
<result_fields>-/bic/zacustsls = ' '.
APPEND <result_fields> TO result1.
ELSEIF wa_stat2-/bic/zotlkvgr1 = 2 .
<result_fields>-/bic/zspjpstat = 'Y'.
<result_fields>-/bic/zacustsls = wa_stat2-/bic/zcustsls.
"<result_fields>-/BIC/ZOUTGRP = wa_stat2-/BIC/ZOUTGRP.
"<RESULT_FIELDS>-/BIC/ZMATERIAL = ' '.
<result_fields>-/bic/znetsle = ' '.
<result_fields>-/bic/zicustsls = ' '.
APPEND <result_fields> TO result1.
ENDIF.
ENDIF.
ENDLOOP.
ENDIF.
ENDLOOP.
UNASSIGN: <result_fields>.
LOOP AT result1 ASSIGNING <result_fields>.
IF <result_fields>-/bic/znetsle LT 0.
<result_fields>-flag = '1'.
ELSE.
<result_fields>-flag = '0'.
ENDIF.
ENDLOOP.
SORT result1 BY /bic/zemplye /bic/zrouteid /bic/zouttyp
/bic/zoutgrp /bic/zcustsls distr_chan salesorg
division calmonth flag
DESCENDING
/bic/znetsle
DESCENDING.
DELETE ADJACENT DUPLICATES FROM result1 COMPARING /bic/zemplye
/bic/zrouteid /bic/zouttyp /bic/zoutgrp /bic/zcustsls
distr_chan salesorg division calmonth.
REFRESH RESULT_PACKAGE.
FREE RESULT_PACKAGE.
RESULT_PACKAGE[] = result1[].
LOOP AT RESULT_PACKAGE ASSIGNING <result_fields>.
v_count = v_count + 1.
<result_fields>-record = v_count.
CLEAR wa_stat.
READ TABLE it_stat INTO wa_stat
WITH KEY /bic/zemplye = <result_fields>-/bic/zemplye
/bic/zcustsls = <result_fields>-/bic/zcustsls.
IF sy-subrc = 0.
IF wa_stat-/bic/zotlkvgr1 NE 2.
<result_fields>-/bic/zspjpstat = 'N'.
<result_fields>-/bic/zicustsls = <result_fields>-/bic/zcustsls
.
ELSEIF wa_stat-/bic/zotlkvgr1 = 2.
<result_fields>-/bic/zspjpstat = 'Y'.
<result_fields>-/bic/zacustsls = <result_fields>-/bic/zcustsls
.
ENDIF.
ENDIF.
IF <result_fields>-/bic/zacustsls IS INITIAL
AND <result_fields>-/bic/zicustsls IS INITIAL .
<result_fields>-/bic/zicustsls = <result_fields>-/bic/zcustsls.
ENDIF.
ENDLOOP.
*$*$ end of routine - insert your code only before this line *-*
ENDMETHOD. "end_routine
Thanks.
Good Doc Suman...Keep it up..!!