In SAP, for better performance, instead of using nested loops, we can use the index looping technique.
The following sample code explains the usage of index looping and shows the difference between nested loops and index looping:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 |
*&--------------------------------------------------------------------&* *& Program Description: &* *& ----------------------- &* *& This demo program will demonstrate the use of index looping. &* *& &* *& &* *& Author: ABAPCOOKBOOK &* *& Website: www.abapcookbook.com &* ************************************************************************ REPORT ZDEMOINDEXLOOPING. *Internal tables and structures: DATA: lt_bkpf TYPE STANDARD TABLE OF bkpf, lt_bseg TYPE STANDARD TABLE OF bseg, lst_bkpf TYPE bkpf, lst_bseg TYPE bseg. *Variables: DATA: gv_stime TYPE i, "Start Time gv_etime TYPE i, "End Time gv_tdiff TYPE i, "Time Difference gv_counter TYPE i, "Record Counter gv_tabix TYPE sy-tabix. "Tabix Position *------------------------------------* *DUMMY RETRIEVAL: * *------------------------------------* *Dummy retrieval for demo purposes. *Data at header level. SELECT * FROM bkpf INTO TABLE lt_bkpf UP TO 10 ROWS. IF sy-subrc EQ 0. * Sort and delete adjacent duplicates not necessary as * we are sorting and deleting by primary keys. However, we * will leave like that to remember that its a best practice * to sort and delete adjacents duplicates when using for * all entries. SORT lt_bkpf BY bukrs belnr gjahr. DELETE ADJACENT DUPLICATES FROM lt_bkpf COMPARING bukrs belnr gjahr. ENDIF. *If the table is not empty, proceed. Please note that *this is necessary when doing for all entries because *if the table 'LT_BKPF' is empty, the following retrieval *will retrieve all the entries from table BSEG. IF lt_bkpf[] IS NOT INITIAL. * Data at item level. SELECT * FROM bseg INTO TABLE lt_bseg FOR ALL ENTRIES IN lt_bkpf WHERE bukrs EQ lt_bkpf-bukrs AND belnr EQ lt_bkpf-belnr AND gjahr EQ lt_bkpf-gjahr. IF sy-subrc EQ 0. * Sorting not required but its just for * information purposes. SORT lt_bseg BY bukrs belnr gjahr. ENDIF. ENDIF. *------------------------------------* *NESTED LOOPS: * *------------------------------------* *Get the starting time. GET RUN TIME FIELD gv_stime. *Nested Loops: *Loop at header level. LOOP AT lt_bkpf INTO lst_bkpf. * Loop at item level. LOOP AT lt_bseg INTO lst_bseg WHERE bukrs EQ lst_bkpf-bukrs AND belnr EQ lst_bkpf-belnr AND gjahr EQ lst_bkpf-gjahr. * Do some processing. gv_counter = gv_counter + 1. ENDLOOP. ENDLOOP. *Get the ending time. GET RUN TIME FIELD gv_etime. *Get the time difference, which will be the execution time *the code was executed. gv_tdiff = gv_etime - gv_stime. *Output the time difference. WRITE:/1(61) sy-uline. WRITE: /1 sy-vline, 2(40) 'Taking Taken Using Nested Loops:', gv_tdiff, 41 sy-vline, 50(10) gv_tdiff, 61 sy-vline. *------------------------------------* *INDEX LOOPING: * *------------------------------------* CLEAR: gv_counter. *Get the starting time. GET RUN TIME FIELD gv_stime. *Nested Loops: *Loop at header level. LOOP AT lt_bkpf INTO lst_bkpf. * We will check if we have the header record * at item level. READ TABLE lt_bseg TRANSPORTING NO FIELDS WITH KEY bukrs = lst_bkpf-bukrs belnr = lst_bkpf-belnr gjahr = lst_bkpf-gjahr BINARY SEARCH. * If we have a match, get the tabix position * at which we found the header level record in * the item level table. IF sy-subrc EQ 0. * Get the tabix position of the line found * in 'LT_BSEG'. The tabix position will be * used to start the next loop at that position. gv_tabix = sy-tabix. * Loop at item level. * Here, we will start looping in the table 'LT_BSEG' * using the tabix position found above. LOOP AT lt_bseg INTO lst_bseg FROM gv_tabix. * Here, we will check if the current item level * record still match the header level record. If not, * means that we can exit the loop and take the next * header level record. IF lst_bkpf-bukrs NE lst_bseg-bukrs OR lst_bkpf-belnr NE lst_bseg-belnr OR lst_bkpf-gjahr NE lst_bseg-gjahr. * Clearing necessary items. CLEAR: gv_tabix, lst_bseg. * Okay, go out of the loop. EXIT. ENDIF. * If the IF statement above has failed, means that * that line at header level matches the line at item * level, do some processing. * Do some processing. gv_counter = gv_counter + 1. * Clearing necessary items. CLEAR: lst_bseg. ENDLOOP. ENDIF. * Clearing necessary items. CLEAR: lst_bkpf. ENDLOOP. *Get the ending time. GET RUN TIME FIELD gv_etime. *Get the time difference, which will be the execution time *the code was executed. gv_tdiff = gv_etime - gv_stime. *Output the time difference. WRITE:/1(61) sy-uline. WRITE: /1 sy-vline, 2(40) 'Taking Taken Using Index Looping:', gv_tdiff, 41 sy-vline, 50(10) gv_tdiff, 61 sy-vline. WRITE:/1(61) sy-uline. |
The results clearly shows that index looping is much better than nested loops.