When you loop around an internal table within your ABAP code using a where clause the loop command still processes every
line in the table to check if it meets the correct criteria.
This is probably not a problem in many cases as it's the processing within the loop that takes the time rather
than the actual loop, having said that it's always a good idea to avoid any unnecessary processing.
There will also be a number of cases where you have thousands/millions of records but you know that based on your
sort criteria only a few of them will match your where clause and be all together somewhere in the middle of the table.
The following code demonstrates the use of a parallel cursor, which allows you to go straight to the first of
these records and stop processing immediately after you have processed the last one. This can significantly reduce
the processing time of your ABAP reports, especially those that have large itab loops or nested loops. The example
below reduces the processing time of a very simple nested loop of KEKO and KEPH from 302 seconds to less than 1 seconds.
*&---------------------------------------------------------------------* *& Report ZREP_PARALLEL_CURSOR *&---------------------------------------------------------------------* *& *& SAP ABAP functionality *& ********************** *& Select data from database table into internal table *& Loop at internal table *& Loop using Parallel cursor functionality *& Write info to output report screen *& SORT internal table *& Calculate runtime of an ABAP report using GET RUN TIME FIELD *& Convert GET RUN TIME FIELD to seconds *&---------------------------------------------------------------------* REPORT zrep_parallel_cursor. REPORT zrep_parallel_cursor. DATA: it_keko TYPE STANDARD TABLE OF keko, wa_keko LIKE LINE OF it_keko, it_keph TYPE STANDARD TABLE OF keph, wa_keph LIKE LINE OF it_keph. DATA: d_mat_cost TYPE keph-kst001, d_lab_cost TYPE keph-kst004, d_over_head TYPE keph-kst010, d_ext_purch TYPE keph-kst014, d_misc_cost TYPE keph-kst002, ld_starttime TYPE i, ld_endtime TYPE i, ld_runtime TYPE i. ************************************************************** * START-OF-SELECTION START-OF-SELECTION. SELECT * INTO TABLE it_keko FROM keko. SELECT * INTO TABLE it_keph FROM keph. * Table must be sorted to ensure all required records are together SORT it_keph BY kalnr kalka bwvar kadky. * Perform actual processing PERFORM get_cost_values. *----------------------------------------------------------------------* FORM get_cost_values. * Determine start position and then process all records for given key * from that starting point GET RUN TIME FIELD ld_starttime. LOOP AT it_keko INTO wa_keko. clear:d_mat_cost, d_lab_cost, d_over_head, d_ext_purch,d_misc_cost. * it_keph is sorted on kalnr kalka bwvar kadky. READ TABLE it_keph TRANSPORTING NO FIELDS WITH KEY kalnr = wa_keko-kalnr kalka = wa_keko-kalka bwvar = wa_keko-bwvar kadky = wa_keko-kadky BINARY SEARCH. IF sy-subrc = 0. * Loop at itab from first record found (sy-tabix) until record * no-longer matches your criteria. LOOP AT it_keph INTO wa_keph FROM sy-tabix. IF wa_keph-kalnr = wa_keko-kalnr AND wa_keph-kalka = wa_keko-kalka AND wa_keph-bwvar = wa_keko-bwvar AND wa_keph-kadky = wa_keko-kadky. * Key match d_mat_cost = d_mat_cost + wa_keph-kst001. d_lab_cost = d_lab_cost + wa_keph-kst004. d_over_head = d_over_head + wa_keph-kst010. d_ext_purch = d_ext_purch + wa_keph-kst014. d_misc_cost = d_misc_cost + wa_keph-kst002 + wa_keph-kst003 + wa_keph-kst005 + wa_keph-kst006 + wa_keph-kst007 + wa_keph-kst008 + wa_keph-kst009 + wa_keph-kst011 + wa_keph-kst012 + wa_keph-kst013 + wa_keph-kst015 + wa_keph-kst016 + wa_keph-kst017 + wa_keph-kst018 + wa_keph-kst019 + wa_keph-kst020 + wa_keph-kst021 + wa_keph-kst022 + wa_keph-kst023 + wa_keph-kst024 + wa_keph-kst025 + wa_keph-kst026 + wa_keph-kst027 + wa_keph-kst028 + wa_keph-kst029 + wa_keph-kst030 + wa_keph-kst031 + wa_keph-kst032 + wa_keph-kst033 + wa_keph-kst034 + wa_keph-kst035 + wa_keph-kst036 + wa_keph-kst037 + wa_keph-kst038 + wa_keph-kst039 + wa_keph-kst040. ELSE. * End of required records EXIT. " Exit loop ENDIF. ENDLOOP. ENDIF. IF wa_keko-losgr GE 1. d_mat_cost = d_mat_cost / wa_keko-losgr. d_lab_cost = d_lab_cost / wa_keko-losgr. d_over_head = d_over_head / wa_keko-losgr. d_ext_purch = d_ext_purch / wa_keko-losgr. d_misc_cost = d_misc_cost / wa_keko-losgr. check not d_mat_cost is INITIAL. WRITE:/ d_mat_cost, d_lab_cost, d_over_head, d_ext_purch,d_misc_cost. ENDIF. ENDLOOP. GET RUN TIME FIELD ld_endtime. ld_runtime = ld_endtime - ld_starttime. "time in micro seconds WRITE:/ ld_runtime, 'micro, nano or what ever seconds'. ld_runtime = ld_runtime / 1000000. "time in seconds WRITE:/ ld_runtime, 'seconds'. ENDFORM. " GET_COST_VALUES
Same code not using parellel cursor increases the runtime from 1 to 302 seconds
If you then run this exact same example ABAP code but without the use of the parallel cursor functionality
you can see that the execution time increases significantly. Using the data on my test system which has
36,000 records in KEKO and 57,000 records in KEPH the runtime time goes from 1 second to 302 seconds,
which is massive and hopefully demonstrates the importance of using parallel cursors.
*&---------------------------------------------------------------------* *& Report ZREP_NONE_PC *&---------------------------------------------------------------------* REPORT zrep_none_pc. DATA: it_keko TYPE STANDARD TABLE OF keko, wa_keko LIKE LINE OF it_keko, it_keph TYPE STANDARD TABLE OF keph, wa_keph LIKE LINE OF it_keph. DATA: d_mat_cost TYPE keph-kst001, d_lab_cost TYPE keph-kst004, d_over_head TYPE keph-kst010, d_ext_purch TYPE keph-kst014, d_misc_cost TYPE keph-kst002, ld_starttime TYPE i, ld_endtime TYPE i, ld_runtime TYPE i. ************************************************************** * START-OF-SELECTION START-OF-SELECTION. SELECT * INTO TABLE it_keko FROM keko. * UP TO 20 rows. SELECT * INTO TABLE it_keph FROM keph. * Table must be sorted to ensure all required records are together SORT it_keph BY kalnr kalka bwvar kadky. * Perform actual processing PERFORM get_cost_values. *----------------------------------------------------------------------* FORM get_cost_values. GET RUN TIME FIELD ld_starttime. LOOP AT it_keko INTO wa_keko. CLEAR:d_mat_cost, d_lab_cost, d_over_head, d_ext_purch,d_misc_cost. LOOP AT it_keph INTO wa_keph WHERE kalnr = wa_keko-kalnr AND kalka = wa_keko-kalka AND bwvar = wa_keko-bwvar AND kadky = wa_keko-kadky. * Key match d_mat_cost = d_mat_cost + wa_keph-kst001. d_lab_cost = d_lab_cost + wa_keph-kst004. d_over_head = d_over_head + wa_keph-kst010. d_ext_purch = d_ext_purch + wa_keph-kst014. d_misc_cost = d_misc_cost + wa_keph-kst002 + wa_keph-kst003 + wa_keph-kst005 + wa_keph-kst006 + wa_keph-kst007 + wa_keph-kst008 + wa_keph-kst009 + wa_keph-kst011 + wa_keph-kst012 + wa_keph-kst013 + wa_keph-kst015 + wa_keph-kst016 + wa_keph-kst017 + wa_keph-kst018 + wa_keph-kst019 + wa_keph-kst020 + wa_keph-kst021 + wa_keph-kst022 + wa_keph-kst023 + wa_keph-kst024 + wa_keph-kst025 + wa_keph-kst026 + wa_keph-kst027 + wa_keph-kst028 + wa_keph-kst029 + wa_keph-kst030 + wa_keph-kst031 + wa_keph-kst032 + wa_keph-kst033 + wa_keph-kst034 + wa_keph-kst035 + wa_keph-kst036 + wa_keph-kst037 + wa_keph-kst038 + wa_keph-kst039 + wa_keph-kst040. ENDLOOP. IF wa_keko-losgr GE 1. d_mat_cost = d_mat_cost / wa_keko-losgr. d_lab_cost = d_lab_cost / wa_keko-losgr. d_over_head = d_over_head / wa_keko-losgr. d_ext_purch = d_ext_purch / wa_keko-losgr. d_misc_cost = d_misc_cost / wa_keko-losgr. ENDIF. CHECK NOT d_mat_cost IS INITIAL. WRITE:/ d_mat_cost, d_lab_cost, d_over_head, d_ext_purch,d_misc_cost. ENDLOOP. GET RUN TIME FIELD ld_endtime. ld_runtime = ld_endtime - ld_starttime. "time in micro seconds WRITE:/ ld_runtime, 'micro, nano or what ever seconds'. ld_runtime = ld_runtime / 1000000. "time in seconds WRITE:/ ld_runtime, 'seconds'. ENDFORM. " GET_COST_VALUES