Avoiding Nested Loops Using Parallel Cursors
Background: Performance of program, function modules, BAdi or any piece of code would drastically go down when:
Sample program run with different number of BKPF and BSEG tables entries is shown below:
Observation:
One can observe that as the data increases, the time taken for nested loop increases drastically, at the same time, Parallel cursor method did not have any considerable time.
Verdict: Use parallel cursor method whenever there is a need to have nested loop.
Method:
Assume you fill up bkpf_tab and bseg_tab.
Code for normal nested loop: ( I consider this as UGLY code from now onwards)
Code for Parallel Cursor:
Go through these code and post your comments
Analysis:
In the so called UGLY code, for every record in parent table (BKPF), the whole child table (BSEG) is searched and hence the delay. In Parallel cursor code both the tables are sorted and child table is not accessed completely, instead the index is stored in every iteration of the child table, once all the child records for current parent record is over, the index of the current child record is used for accessing first child record of next parent entry without searching the entire table. This is doen using 'FROM' clause of the loop. The where condition for the child loop should be avoided at any cost. Store the index and use the same for the next parent record. As the tables are sorted, this method should work excellently.
Going forward:
I would add a checkilist item for my code review to check for Parallel cursor for any place where a Nested loop is involved.
- Nested loops are used
- Corresponding internal tables are very huge
- When child table is larger than the parent table
Sample program run with different number of BKPF and BSEG tables entries is shown below:

One can observe that as the data increases, the time taken for nested loop increases drastically, at the same time, Parallel cursor method did not have any considerable time.
Verdict: Use parallel cursor method whenever there is a need to have nested loop.
Method:
Assume you fill up bkpf_tab and bseg_tab.
Code for normal nested loop: ( I consider this as UGLY code from now onwards)
loop at bkpf_tab into bkpf_lin.
bkpf_reads = bkpf_reads + 1.
loop at bseg_tab into bseg_lin where
bukrs = bkpf_lin-bukrs and
belnr = bkpf_lin-belnr and
gjahr = bkpf_lin-gjahr.
bseg_reads = bseg_reads + 1.
endloop.
endloop.
Code for Parallel Cursor:
SORT: bkpf_tab BY bukrs belnr gjahr,
bseg_tab BY bukrs belnr gjahr.
bseg_index = 1.
LOOP AT bkpf_tab INTO bkpf_lin.
bkpf_reads = bkpf_reads + 1.
LOOP AT bseg_tab INTO bseg_lin FROM bseg_index.
IF bseg_lin-bukrs <> bkpf_lin-bukrs OR
bseg_lin-belnr <> bkpf_lin-belnr OR
bseg_lin-gjahr <> bkpf_lin-gjahr.
bseg_index = sy-tabix.
EXIT.
ELSE.
bseg_reads = bseg_reads + 1.
ENDIF.
ENDLOOP.
ENDLOOP.
Go through these code and post your comments
Analysis:
In the so called UGLY code, for every record in parent table (BKPF), the whole child table (BSEG) is searched and hence the delay. In Parallel cursor code both the tables are sorted and child table is not accessed completely, instead the index is stored in every iteration of the child table, once all the child records for current parent record is over, the index of the current child record is used for accessing first child record of next parent entry without searching the entire table. This is doen using 'FROM' clause of the loop. The where condition for the child loop should be avoided at any cost. Store the index and use the same for the next parent record. As the tables are sorted, this method should work excellently.
Going forward:
I would add a checkilist item for my code review to check for Parallel cursor for any place where a Nested loop is involved.
Labels: Nested Loop, Optimization, Parallel Cursor, Performance, SAP