Parallel
Cursor
Traditionally in abap, the
consultant use where clause in nested loop, this is very common but there is
big issue with performance when using where clause in nested loop with table,
EKKO, VBAK, BKPF etc.
The problem with this method is
for each record in the first internal table, when system checking for the
matching record in second table, it search all the records starting from index
1 to the last record.
To overcome the performance issue ,
there is a method called parallel cursor, in this method before the loop in
second table, first we read the index of the matching record in second table ,
and then loop get starts from the that index only and exist , when record not
match. In this method for each record of first table system check and perform
logic only for the match records of second table
Traditional
Method:
loop at gt_ekko into gs_ekko.
|
|||||||
1
|
4500000010
|
||||||
2
|
4500000011
|
||||||
3
|
4500000012
|
||||||
4
|
4500000013
|
||||||
5
|
4500000014
|
||||||
6
|
4500000015
|
||||||
loop at gt_ekpo into gs_ekpo where ebeln = gs_ekk-ebeln.
|
|||||||
1
|
4500000010
|
10
|
|||||
2
|
4500000010
|
20
|
|||||
3
|
4500000011
|
10
|
|||||
4
|
4500000011
|
20
|
|||||
5
|
4500000012
|
10
|
|||||
6
|
4500000013
|
10
|
|||||
7
|
4500000014
|
10
|
|||||
8
|
4500000015
|
10
|
|||||
clear : gs_ekpo.
|
|||||||
endloop.
|
|||||||
clear : gs_ekko.
|
|||||||
endloop.
|
|||||||
Parallel
Cursor:
loop at gt_ekko into gs_ekko.
|
|||||||
1
|
4500000010
|
||||||
2
|
4500000011
|
||||||
3
|
4500000012
|
||||||
4
|
4500000013
|
||||||
5
|
4500000014
|
||||||
6
|
4500000015
|
||||||
Reab table gt_ekpo into gs_ekpo with key ebeln = gs_ekko-ebeln
|
|||||||
if sy-subrc = 0.
|
|||||||
loop at gt_ekpo into gs_ekpo from sy-tabix
|
|||||||
if gs_ekko-ebeln ne gs_ekpo-ebeln.
|
|||||||
exit
|
|||||||
endif.
|
|||||||
1
|
4500000010
|
10
|
|||||
2
|
4500000010
|
20
|
|||||
3
|
4500000011
|
10
|
|||||
4
|
4500000011
|
20
|
|||||
5
|
4500000012
|
10
|
|||||
6
|
4500000013
|
10
|
|||||
7
|
4500000014
|
10
|
|||||
8
|
4500000015
|
10
|
|||||
clear : gs_ekpo.
|
|||||||
endloop.
|
|||||||
endif.
|
|||||||
clear : gs_ekko.
|
|||||||
endloop.
|
|||||||
code using where clause
REPORT ZAFAR_NESTED_LOOP.
data : lv_starttime type TIMESTAMPL,
lv_endtime type TIMESTAMPL,
lv_runtime type TIMESTAMPL.
select * from ekko into TABLE @data(gt_ekko) UP TO 10000 ROWS.
if gt_ekko[] is NOT INITIAL.
select * from ekpo into TABLE @data(gt_ekpo) FOR ALL ENTRIES IN @gt_ekko
WHERE EBELN = @GT_EKKO-EBELN.
endif.
SORT GT_EKKO.
SORT GT_EKPO.
GET TIME STAMP FIELD LV_STARTTIME.
LOOP at gt_ekko into data(gs_ekko).
loop at gt_ekpo into data(gs_ekpo) WHERE ebeln = gs_ekko-ebeln.
clear : gs_ekpo.
endloop.
clear : gs_ekko.
endloop.
get TIME STAMP FIELD LV_ENDTIME.
LV_RUNTIME = LV_ENDTIME - LV_STARTTIME.
write : / lv_runtime.
write : / LV_ENDTIME.
write : / LV_STARTTIME.
output in 6.7 seconds
Code using Parallel cursor method :
REPORT ZAFAR_NESTED_LOOP_PC.
data : lv_starttime type TIMESTAMPL,
lv_endtime type TIMESTAMPL,
lv_runtime type TIMESTAMPL.
select * from ekko into TABLE @data(gt_ekko) UP TO 10000 ROWS.
if gt_ekko[] is NOT INITIAL.
select * from ekpo into TABLE @data(gt_ekpo) FOR ALL ENTRIES IN @gt_ekko
WHERE EBELN = @GT_EKKO-EBELN.
endif.
SORT GT_EKKO.
SORT GT_EKPO.
GET TIME STAMP FIELD LV_STARTTIME.
LOOP at gt_ekko into data(gs_ekko).
read TABLE gt_ekpo into data(gs_ekpo) with key ebeln = gs_ekko-ebeln BINARY SEARCH.
if sy-subrc = 0.
loop at gt_ekpo into gs_ekpo FROM sy-tabix.
if gs_ekpo-ebeln ne gs_ekko-ebeln.
exit.
endif.
clear : gs_ekpo.
endloop.
endif.
clear : gs_ekko.
endloop.
get TIME STAMP FIELD LV_ENDTIME.
LV_RUNTIME = LV_ENDTIME - LV_STARTTIME.
write : / lv_runtime.
write : / LV_ENDTIME.
write : / LV_STARTTIME.
data : lv_starttime type TIMESTAMPL,
lv_endtime type TIMESTAMPL,
lv_runtime type TIMESTAMPL.
select * from ekko into TABLE @data(gt_ekko) UP TO 10000 ROWS.
if gt_ekko[] is NOT INITIAL.
select * from ekpo into TABLE @data(gt_ekpo) FOR ALL ENTRIES IN @gt_ekko
WHERE EBELN = @GT_EKKO-EBELN.
endif.
SORT GT_EKKO.
SORT GT_EKPO.
GET TIME STAMP FIELD LV_STARTTIME.
LOOP at gt_ekko into data(gs_ekko).
read TABLE gt_ekpo into data(gs_ekpo) with key ebeln = gs_ekko-ebeln BINARY SEARCH.
if sy-subrc = 0.
loop at gt_ekpo into gs_ekpo FROM sy-tabix.
if gs_ekpo-ebeln ne gs_ekko-ebeln.
exit.
endif.
clear : gs_ekpo.
endloop.
endif.
clear : gs_ekko.
endloop.
get TIME STAMP FIELD LV_ENDTIME.
LV_RUNTIME = LV_ENDTIME - LV_STARTTIME.
write : / lv_runtime.
write : / LV_ENDTIME.
write : / LV_STARTTIME.
Same records using parallel cursor method output in 0.0089 seconds.
3 Comments
Very clever procedure, particularly for those huge tables like BKPF, EKKO and Controlling tables. Sometimes it took 2 hrs during the dialogue mode being used by other online users !!
ReplyDeleteThanks
Kumar Mitra
Very usefull concept you teach. thanks
ReplyDeleteYes ..Simple & excellent
ReplyDelete