CEN Com IT MET ABAP Recommending Performances V2
CEN Com IT MET ABAP Recommending Performances V2
CEN Com IT MET ABAP Recommending Performances V2
Document information :
Team
Technical - Development
Responsible
Philippe Bride
Version
V2
Last modification on
02/09/2004
Status
Validated
Version
Date
Author
/var/www/apps/conversion/tmp/scratch_2/261948625.doc
Modification
Page 1 of 38
last modification: 2/28/2015
TABLE OF CONTENTS
1.
INTRODUCTION.................................................................................................................................4
2.
NOTATIONS..........................................................................................................................................5
2.1.
2.2.
3.
PICTOGRAMS....................................................................................................................................5
NOTATIONS IN THE ALGORITHMS.....................................................................................................5
GENERAL RULES................................................................................................................................6
3.1.
3.2.
3.3.
3.4.
3.5.
4.
5.
SELECTED FIELDS.............................................................................................................................7
THE <WHERE> CLAUSE.....................................................................................................................7
THE <SELECT> INSTRUCTION........................................................................................................8
INFORMATION STRUCTURES.............................................................................................................12
6.
7.
DATA DICTIONARY..........................................................................................................................21
7.1.
7.2.
7.3.
8.
TABLE CREATION.............................................................................................................................21
BUFFERING.......................................................................................................................................22
INDEXING.........................................................................................................................................22
MASS TREATMENTS........................................................................................................................23
8.1.
8.2.
8.3.
9.
DELETION.........................................................................................................................................23
MODIFICATION...............................................................................................................................25
INSERTION........................................................................................................................................26
10.
10.1.
10.2.
10.3.
10.4.
/var/www/apps/conversion/tmp/scratch_2/261948625.doc
Page 2 of 38
last modification: 2/28/2015
10.5.
/var/www/apps/conversion/tmp/scratch_2/261948625.doc
Page 3 of 38
last modification: 2/28/2015
1. Introduction
The objective of this documentation is not to provide solutions regarding performance problems
from an ABAP point of view but to suggest some methods, which will improve the execution run
time of specific programs.
In the development phase, the programmer must always keep in mind that the way in which he or
she codes has a direct impact on the execution run time.
Considering significant volumes of the databases at EUROVIA, the least access "badly coded" on a
table, for example MSEG, can appear catastrophic. Indeed in most of the cases, accesses to the
bases represent the major part of the total execution time of a program. That is why the developer
must be rigorous when he must code readings, insertions, suppressions and modifications of
recordings in the tables.
First of all, in Chapters 2 and 3, the notations used in this document and some general rules for
developing are presented.
The two following chapters deal with data selection: on one table with the <SELECT> instruction,
then on many tables with different loops and joins.
Chapter 6 treats the aspects of the <COMMIT> and <ROLLBACK> instructions.
Chapter 7 provides some advice about the data dictionary.
Chapter 8 explains how to carry out optimized mass treatments: deletion, modification, and
insertion.
Chapter 9 brings several remarks on some instructions as the nested loops.
Last but not least, Chapter 10 provides some solutions to big problems of performance in order to
make high-level performance.
/var/www/apps/conversion/tmp/scratch_2/261948625.doc
Page 4 of 38
last modification: 2/28/2015
2. Notations
2.1. Pictograms
High performance.
Tool to use in priority.
Low performance.
Tool to avoid except in some particular cases.
Very low performance.
Forbidden tool.
In some very particular cases, if the use of the tool seems essential, the
developer must indicate it inside the program and talk about it with the
Performance team before releasing the order.
Significant remark.
Trap to avoid.
Informations
Signification
Name of a transparent table (ORACLE table for example)
Name of an internal table
Name of a work area
Name of a constant
Name of a field symbol
Name of an internal structure
Name of a field of a table
Name of a key of a table
Name of a Select Option
Name of a specific view
Treatment carried out in a program
/var/www/apps/conversion/tmp/scratch_2/261948625.doc
Page 5 of 38
last modification: 2/28/2015
3. General rules
3.1. Database server / Application server
Even if working on the database server is often quicker then working on the application server, it is
recommended to solicit the application server in order to avoid overloading the database sever.
Therefore it is important to:
1. Repatriate the data from the database to the application server,
2. Work on the application server.
SELECT SINGLE
SELECT UP TO 1 ROWS
ENDSELECT
SELECT INTO TABLE wt_table
SELECT INTO TABLE wt_table
FOR ALL ENTRIES
SELECT
ENDSELECT.
Logical databases
Nested select
GROUP BY
ORDER BY
[]CORRESPONDING FIELDS OF []
DISTINCT
/var/www/apps/conversion/tmp/scratch_2/261948625.doc
Page 6 of 38
last modification: 2/28/2015
3.5. Query
Queries are forbidden because programs generated by a Query are not performing at all. Requests
are not optimized, thus execution time is too high.
/var/www/apps/conversion/tmp/scratch_2/261948625.doc
Page 7 of 38
last modification: 2/28/2015
SELECT *
FROM table
After many compared tests, it is proven that the <SELECT SINGLE> instruction seems to
be more efficient that <UP TO 1 ROWS> one. During the use of a <SELECT SINGLE>
instruction, if the field used in the <WHERE> clause is only a part of the primary key, the
Workbench displays a <Warning> message.
Even if the <SELECT *> instruction is very quick at coding, it unfortunately takes up a lot of
memory space in most of the cases. It is recommended to select only the useful fields for the
treatment.
When we are on the instruction which follows <ENDSELECT>, we do not know if we
have gone into the <SELECT> instruction or not. This implies that it is always
necessary to test the return code after the <SELECT> instruction.
Except for the particular cases:
Dynpro updating
SELECT SINGLE *
FROM table
WHERE field2 = xxx.
Page 8 of 38
last modification: 2/28/2015
SELECT *
INTO TABLE wt_table
FROM table
WHERE field1 = xxxx
AND field2 EQ zzz.
IF sy-dbcnt NE 0.
LOOP AT wt_table.
Treatment.
ENDLOOP.
ENDIF.
SELECT SINGLE *
FROM table
WHERE field = xxxx.
After a <SELECT> instruction, data are not systematically sorted in the key order. Hence
data must be sorted in the case of a reuse. But non-justified redundant sorts are forbidden
because they cost a lot in term of performance.
Data sorting
Sorting on the database server.
SELECT *
FROM table
WHERE field1 = xxxx
ORDER BY field2.
Treatment.
EXIT.
ENDSELECT.
/var/www/apps/conversion/tmp/scratch_2/261948625.doc
<INTO> option
This option permits to stock the selected columns in the variables defined by the developer.
SELECT SINGLE *
INTO table
FROM table
WHERE field1 = xxxx.
IF sy-dbcnt NE 0.
wv_field2 = table-field2.
Treatment.
ENDIF.
But it is better to put the fields of the <SELECT> instruction in the same order
of the structure declaration or the internal table in order to be quicker.
/var/www/apps/conversion/tmp/scratch_2/261948625.doc
Page 10 of 38
last modification: 2/28/2015
SELECT SINGLE *
INTO CORRESPONDING FIELDS OF table
FROM table
WHERE key = xxxx.
SELECT SINGLE *
FROM table
WHERE key = xxx.
Structure
DATA: BEGIN OF ws_struct,
field1 LIKE table-field1,
field2 LIKE table-field2,
field3 LIKE table-field3,
END OF ws_struct.
SELECT SINGLE *
INTO CORRESPONDING FIELDS OF ws_struct
FROM table
WHERE field1 = xxxx.
Internal table
DATA : BEGIN OF wt_table OCCURS 0,
field1 LIKE table-field1,
field2 LIKE table-field2,
field3 LIKE table-field3,
END OF wt_table.
SELECT *
INTO CORRESPONDING FIELDS OF wt_table
FROM table
WHERE field1 = xxxx.
APPEND wt_table.
ENDSELECT.
SELECT *
INTO CORRESPONDING FIELDS OF TABLE wt_table
FROM table
WHERE field1 = xxxx.
There are several forms like <INTO CORRESPONDING FIELDS OF TABLE> and <APPENDING
CORRESPONDING FIELDS OF TABLE>
Example:
Given a transparent table with the fields field1, field2, field3, field4 and field5 in this order,
Given an internal table with the fields field1, field 3 and field 4 in this order,
We get:
REFRESH wt_table.
SELECT *
INTO CORRESPONDING FIELDS OF wt_table
FROM table
WHERE field1 = xxxx.
APPEND wt_table.
ENDSELECT.
/var/www/apps/conversion/tmp/scratch_2/261948625.doc
Page 11 of 38
last modification: 2/28/2015
SELECT *
INTO CORRESPONDING FIELDS OF wt_table
FROM table
WHERE field1 = xxxx.
APPEND wt_table.
ENDSELECT.
It enables to accelerate the execution of the <SELECT FOR ALL ENTRIES> instruction
since the volume of the internal table is smaller.
It avoids some dumps of the programs because of a lack of memory in the table2 table
(See the following example)
If we know that the internal table has duplicates, we have to copy the internal table, sort it and
delete its duplicates.
- test the number of recordings
- sort the recordings
- delete the duplicates
SELECT *
INTO TABLE wt_table1
FROM table1
WHERE field1 IN s_field1.
SELECT *
INTO TABLE wt_table2
FROM table2
FOR ALL ENTRIES IN wt_table1
WHERE field1 = wt_table1-field1
AND field2 = xxxx.
Treatment.
/var/www/apps/conversion/tmp/scratch_2/261948625.doc
SELECT *
INTO TABLE wt_table1
FROM table
WHERE field1 IN s_field1.
IF sy-dbcnt NE 0.
SORT wt_table1 BY field1.
DELETE ADJACENT DUPLICATES FROM wt_table1
COMPARING field1.
SELECT *
INTO TABLE wt_table2
FROM table2
FOR ALL ENTRIES IN wt_table1
WHERE field1 = wt_table1-field1
AND field2 = xxxx.
Treatment.
ENDIF.
Page 12 of 38
last modification: 2/28/2015
/var/www/apps/conversion/tmp/scratch_2/261948625.doc
SELECT *
INTO TABLE wt_s631
FROM s631
WHERE vrsio = wv_vrsio
AND
werks = wv_werks
AND
matnr = wv_matnr
AND
sptag >= wv_beginning
AND
sptag <= wv_end.
Where created index is MANDT, VRSIO, WERKS, MATNR
and SPTAG.
Page 13 of 38
last modification: 2/28/2015
Example
Advantage
During a reading on a son segment, it is not necessary to carry out a reading on the parent
segments. Indeed these are implicit.
For example, if a LDB has MKPF as <Father> segment and MSEG as <Son> segment, a <GET> on
MSEG is sufficient to know the data of MSEG and also that of MKPF.
GET mseg.
CHECK mkpf-blart = xx.
Treatment
Another advantage is that each LDB possesses a selection screen, the fields of which are generated
by the BDL.
Performance
This method is forbidden because in SAP R/3 it is far from being the most performing
method for reading data in the databases.
Example
SELECT *
FROM table1
WHERE .
Treatment.
SELECT *
FROM table2
WHERE table1-field1 = table2-field1 AND .
Treatment.
/var/www/apps/conversion/tmp/scratch_2/261948625.doc
Page 14 of 38
last modification: 2/28/2015
Advantage
The developer controls the access to the database.
Drawback
Considering the important number of accesses to the database, this method is not very
performing from the point of view of the execution duration. Therefore it is forbidden
to use it.
5.3. Sub-query
A sub-query solicits the database sever. So, it is not recommended. However, in some particular
cases, we can use it (See Section 10)
Example:
SELECT * FROM table
INTO TABLE wt_table
WHERE field IN ( SELECT FROM WHERE).
5.4. Joins
Principle
Instead of carrying out the selections in many tables from the database, the join permits to carry out
dynamically in memory only one access to the different tables. The join can be assimilated to a
view but the difference is that the join is not defined in the dictionary.
Example
SELECT mkpf~mblnr mkpf~mjahr mseg~zeile mseg~
INTO TABLE wt_table1
FROM mkpf INNER JOIN mseg ON mseg~mblnr = mkpf~mblnr
AND mseg~mjahr = mkpf~mjahr
WHERE mkpf~ =
AND
mseg~ = .
Treatment.
Advantage
The developer maintains that he makes only one access because the code can be interpreted like a
<SELECT* FROM table WHERE Treatment ENDSELECT>.
This is a lot quicker than the method of nested SELECT because there are fewer accesses to the
database.
Drawback
The system needs a lot of memory space because it dynamically creates a pseudo table of pointers
in order to optimize the different accesses to different tables of the join.
The performance problem comes from the fact that the code generated by SAP is interpreted by an
internal layer at SAP and not by the database server itself.
/var/www/apps/conversion/tmp/scratch_2/261948625.doc
Page 15 of 38
last modification: 2/28/2015
Use
The inner join can be only used in the case of a 1 to n relation on the key of type
header data <-> item data.
In the other cases, it is forbidden.
Principle
We choose in a first transparent table some records that are stocked in an internal table. We get in a
second transparent table all the records related to each entry of the first internal table by a condition.
Example
* Selection of data at the top of the table
SELECT * INTO TABLE wt_mkpf FROM mkpf
WHERE
AND
.
IF sy-dbcnt NE 0.
SORT wt_mkpf BY mblnr mjahr.
* Selection of data from the table lines
SELECT * INTO TABLE wt_mseg FROM mseg
FOR ALL ENTRIES IN wt_mkpf
WHERE mblnr = wt_mkpf-mblnr
AND
mjahr = wt_mkpf-mjahr
AND
lgort = wc_lgort.
IF sy-dbcnt NE 0.
SORT wt_mseg BY mblnr mjahr zeile.
* Treatment of the selected data
LOOP AT wt_mseg.
Treatment.
AT NEW mjahr.
CLEAR wt_mkpf.
READ TABLE wt_mkpf WITH KEY mblnr = wt_mseg-mblnr
mjahr = wt_mseg-mjahr
BINARY SEARCH.
Treatment.
ENDAT.
Treatment.
AT END OF mjahr.
Treatment.
ENDAT.
Treatment.
ENDLOOP.
ENDIF.
ENDIF.
It is important to test the number of records returned during the stocking in an internal
table from the first transparent table and to read the second transparent table, only if the
internal table contains at least one record. Indeed, if the test is not done and if the first
table is empty, the access to the second table will provide ALL the records of this table.
/var/www/apps/conversion/tmp/scratch_2/261948625.doc
Page 16 of 38
last modification: 2/28/2015
Advantage
This reduces the number of accesses to the database not only from the data selection but also from
the data processing in the body of the program.
Drawback
In some cases we can choose more data than necessary in reality. Furthermore if there are many
tables to stock it will request a large quantity of memory.
Warning
If there are several identical records, the result given by the clause <for all entries in> will
keep only the first occurrence.
Contents of the ekko table:
ebeln
bukrs
zterm
1000
2000
3000
4000
5000
6000
7000
8000
050C
050C
100D
050C
050C
100D
100D
050C
30J
60J
90J
30F
60F
90F
30J
90F
--------------------------
ebeln
ebelp
bukrs
matnr
menge
1000
1000
2000
2000
3000
3000
6000
6000
010
020
050
060
030
040
010
060
050C
050C
050C
050C
100D
100D
100D
100D
2818
2818
2420
2420
2750
2750
2818
2750
100,00
100,00
200,00
200,00
300,00
500,00
600,00
600,00
ebeln
1000
2000
3000
4000
5000
6000
bukrs
050C
050C
100D
050C
050C
100D
zterm
30J
60J
90J
30F
60F
90F
matnr
menge
1000
2000
3000
3000
6000
2818
2420
2750
2750
2818
100,00
200,00
300,00
500,00
600,00
-------------------------
/var/www/apps/conversion/tmp/scratch_2/261948625.doc
ebeln
ebelp
matnr
menge
1000
1000
2000
2000
3000
010
020
050
060
030
2818
2818
2420
2420
2750
100,00
100,00
200,00
200,00
300,00
Page 17 of 38
last modification: 2/28/2015
2750
600,00
3000
6000
6000
ebeln
4000
1000
5000
2000
6000
3000
040
010
060
2750
2818
2750
bukrs
050C
050C
050C
050C
100D
100D
500,00
600,00
600,00
zterm
30F
30J
60F
60J
90F
90J
matnr
2818
2420
2818
2750
2750
2750
menge
100,00
200,00
600,00
600,00
300,00
500,00
-----------------
bukrs
050C
050C
050C
050C
100D
100D
100D
100D
matnr
2818
2818
2420
2420
2818
2750
2750
2750
menge
100,00
100,00
200,00
200,00
600,00
600,00
300,00
500,00
werks
A000
A001
A000
A001
A000
A000
A001
A001
Solution:
To avoid this major inconvenience, it is compulsory to quote the complete key in the list of fields to be
selected.
5.6. View
Principle
A view is a virtual table which does not have a physical existence and which is composed of
columns belonging to one or many tables. During the first call of the view, the system loads all the
data into a memory table corresponding to the view.
/var/www/apps/conversion/tmp/scratch_2/261948625.doc
Page 18 of 38
last modification: 2/28/2015
Creating a view
As we can see, there are at least four sections to fill
out in order to create a view.
- The name of the database view and its
description
- The list of the different tables used in the
view.
Example
SELECT *
FROM zv_view
WHERE
AND
.
Treatment.
ENDSELECT.
Advantage
There are very few accesses to the database for choosing many records which are in different tables.
Drawback
If we want to optimize all the programs by this method, it should be necessary to create at least as
many views as that of the programs. But it takes a lot of memory space.
Furthermore, if there are many tables in the view, the relation between them must point on a key or
on an index so that the view may be the most performing.
Use
Many views have been created by SAP. So we must use them in priority (instead of using
a inner join).
We must avoid creating new specific views because of the memory space.
Using recommendations
(1=high, 6=low)
1
/var/www/apps/conversion/tmp/scratch_2/261948625.doc
Commentary
Always use it except in the case of a 1 to n relation.
Test if the table is empty, sort the table and delete
Page 19 of 38
last modification: 2/28/2015
duplicates.
Join
View
Sub-query
Not recommended.
Nested select
Forbidden.
Logical
database
Forbidden.
/var/www/apps/conversion/tmp/scratch_2/261948625.doc
Page 20 of 38
last modification: 2/28/2015
WHERE zznom
NE space
OR
zzpavillon NE space.
IF sy-subrc NE 0.
ROLLBACK WORK.
EXIT.
ENDIF.
By extension, after each database correction, it is important to keep the database in a stable
statement. To do this, test the return code of the correction instruction to make a rollback if the sysubrc is not equal to zero.
It is forbidden to use the <COMMIT> instruction in the case of a program that updates
tables by carrying out many treatments to do it (in User-Exit for example).
It is also forbidden to use the <COMMIT> instruction in loop structure.
/var/www/apps/conversion/tmp/scratch_2/261948625.doc
Page 21 of 38
last modification: 2/28/2015
7. Data dictionary
7.1. Table creation
Summary of the parameters for a specific table
Buffering
Table
category
Data
type
Table
maintenance
Delivery
class
Question
Yes
No
Delivery class C
Delivery class A
Tick authorized
SM30/SM31 box and
generate the table
maintenance
Specific program
It is forbidden to buffer
the table.
Complete buffering
Individual buffering
Generic buffering
No buffering
/var/www/apps/conversion/tmp/scratch_2/261948625.doc
Page 22 of 38
last modification: 2/28/2015
7.2. Buffering
Buffering a table is forbidden except in some particular cases (see Section10):
7.3. Indexing
The role of the index is to accelerate the data selection in a table.
An index corresponds to the copy of certain fields of a table. These fields are sorted to access more
quickly to data.
The order of fields in the index is very important to determine the speed of the access to the table.
The drawbacks are:
- An index is like a table, which signifies that it takes up disk space.
- All the indexes of a table are updated at the same time and at each time that there is a correction
carried out at a table (INSERT, DELETE, UPDATE, MODIFY). This implies an update of
more than one table. Therefore there is a degradation of the execution time.
Using an existing index is very good for performance.
However, the creation of an index is not recommended except in some very particular
cases (see Section10).
We must be very careful when we create one index.
/var/www/apps/conversion/tmp/scratch_2/261948625.doc
Page 23 of 38
last modification: 2/28/2015
8. Mass Treatments
8.1. Deletion
Internal Table
If we want to delete many records from an internal table satisfying a condition, it is recommended
to carry out a large suppression instead of a suppression record by record.
Deletion record by record.
LOOP AT wt_table
WHERE field1 = xxx.
DELETE wt_table.
ENDLOOP.
Large deletion.
DELETE FROM wt_table
WHERE field1 = xxx.
Transparent Table
The mass deletion is good when we want to delete records from a transparent table. Instead of
erasing the records one by one, it is advised to stock the records for deletion (only the key fields) in
an internal table with the format of the complete key (even <mandt> field) of the transparent table
and afterwards to use the instruction <DELETE table FROM TABLE wt_table>.
Case 1: The comparison in the <WHERE> clause is made with a constant
Deletion record by record.
Mass deletion
SELECT *
DELETE FROM table
FROM table
WHERE field1 = wc_const.
WHERE field1 = wc_const.
IF sy-subrc = 0.
DELETE table.
ENDIF.
ENDSELECT.
Case 2: The comparison in the <WHERE> clause is made with a variable (a field of wt_table)
- Storage of the data for deletion in an internal table.
Deletion record by record.
- Deletion of the data of the transparent table thanks
to the internal table.
LOOP AT wt_table.
DATA: BEGIN OF wt_table OCCURS 0,
SELECT *
mandt LIKE table-mandt,
FROM table
key1 LIKE table-key1,
WHERE field1 = wt_tablekey2 LIKE table-key2,
field1.
(all the keys of the table)
IF sy-subrc = 0.
END OF wt_table.
DELETE table.
SORT wt_table_tmp BY field1.
ENDIF.
DELETE ADJACENT DUPLICATES FROM wt_table_tmp
ENDSELECT.
COMPARING field1.
ENDLOOP.
SELECT mandt key1 key2 (all the keys)
INTO TABLE wt_table
FROM table
FOR ALL ENTRIES IN wt_table_tmp
WHERE field1 = wt_table_tmp-field1.
IF sy-dbcnt NE 0.
DELETE table FROM TABLE wt_table.
ENDIF.
/var/www/apps/conversion/tmp/scratch_2/261948625.doc
Page 24 of 38
last modification: 2/28/2015
Remark: If we know that the internal table has no duplicate, it is not useful to sort it beforehand.
/var/www/apps/conversion/tmp/scratch_2/261948625.doc
Page 25 of 38
last modification: 2/28/2015
8.2. Modification
Internal table
If we wish to modify the contents of one or many fields of a table for some records, it is
recommended to carry out a mass correction instead of a correction record by record.
Correction record by record
LOOP AT wt_table
WHERE field1 = xxx.
wt_table-field2 = aaa.
wt_table-field3 = bbb.
MODIFY wt_table.
ENDLOOP.
Mass correction
CLEAR wt_table.
wt_table-field2
wt_table-field3
MODIFY wt_table
TRANSPORTING
WHERE field1
= aaa.
= bbb.
field2 field3
= xxx.
Transparent table
Mass correction is good too when we want to correct a transparent table. We can use the
<UPDATE> instruction. The main advantage of this statement is that it is quick. But it does not
make any check.
Case 1: Use of the <UPDATE> instruction
Modification record by record
SELECT * FROM table
WHERE field3 = wc_const
field1 = wc_const1.
field2 = wc_const2.
Mass modification
The <UPDATE> instruction does
not make any check.
UPDATE table
SET field1 = wc_const1
Field2 = wc_const2
WHERE field3 = wc_const.
MODIFY table.
ENSELECT.
We can use also stock the corrections in an internal table with the format of the transparent table
and afterwards use the <MODIFY table FROM TABLE wt_table> instruction. This instruction
is more costly than the <UPDATE> one but its advantage is that it makes some checks (insertion or
modification for example).
Case 2: Use of the <MODIFY table FROM TABLE wt_table> instruction
Correction record by record
LOOP AT wt_table.
table-field1 = wt_table-field4.
table-field2 = wt_table-field5.
MODIFY table.
ENDLOOP.
/var/www/apps/conversion/tmp/scratch_2/261948625.doc
ENDIF.
Remark: If we know that the internal table has no duplicate, it is not useful to sort it beforehand.
8.3. Insertion
Internal table
If we wish to append an entire internal table (wt_table1) to another internal table (wt_table2), we
can use the <APPEND LINES OF wt_table1 TO wt_table2> statement.
The wt_table1 table must have the same structure as the wt_table2 table.
Performance
This method of appending lines of one table to another is about 3 to 4 times faster than appending
them line by line in a loop.
LOOP AT wt_table1.
MOVE wt_table1 TO wt_table2.
APPEND wt_table2.
ENDLOOP.
Transparent table
If we wish to insert some records into a transparent table, it is preferable to stock them in an internal
table, sort this internal table in order to suppress then possible duplicates and insert these changed
records into the transparent table.
Remark: If we know that the internal table has no duplicate, it is not useful to sort it beforehand.
Insertion record by record
LOOP treatment.
table-field1 = .
table-field2 = .
INSERT table.
ENDLOOP.
/var/www/apps/conversion/tmp/scratch_2/261948625.doc
Page 27 of 38
last modification: 2/28/2015
To carry out a direct reading on an internal table, it is better to make a <READ TABLE wt_table
WITH KEY field1 = wv_field1 BINARY SEARCH> because the data research will be
performed by dichotomy and not sequentially.
The ASCENDING sort on the reading key is compulsory. Otherwise, the <READ TABLE
wt_table WITH KEY field1 = wv_field1 BINARY SEARCH> will give a bad result.
Data research by dichotomy
/var/www/apps/conversion/tmp/scratch_2/261948625.doc
Page 28 of 38
last modification: 2/28/2015
A good solution
SORT wt_table2 BY key. (if wt_table2 is not empty)
LOOP AT wt_table1. (or loop from index, loop where, do)
Treatment.
READ TABLE wt_table2 WITH KEY key BINARY SEARCH.
IF sy-subrc = 0.
Treatment1.
MODIFY wt_table2 INDEX sy-tabix.
ELSE.
Treatment2.
INSERT wt_table2 INDEX sy-tabix.
ENDIF.
Treatment.
ENDLOOP.
9.3. Loop
The ABAP/4 language possesses instructions, which permit to manage the control breaks in internal
tables.
Control breaks
The instructions between <AT > and <ENDAT> are executed only:
AT FIRST
AT LAST
AT NEW
AT END OF
The tables must be sorted before using <AT NEW> and <AT END OF> instructions.
For SAP, the <AT NEW / AT END OF> instructions are executed only if there is at least a
byte which changes its value between the first byte of the buffer in the table and the last
byte of the specified zone in the <AT NEW/AT END OF>.
Example:
Given an internal table declared as follows:
DATA : BEGIN OF wt_table OCCURS 0,
field1 LIKE table-field1,
field2 LIKE table-field2,
field3 LIKE table-field3,
END OF wt_table.
If we code <AT NEW/AT END OF field2>, it is sufficient that the value of the field1
changes so that the instructions associated to the break on field2 could be executed.
/var/www/apps/conversion/tmp/scratch_2/261948625.doc
Page 29 of 38
last modification: 2/28/2015
wt_table1 OCCURS
0,
LIKE wt_table1_key,
LIKE table4-field4,
LIKE table5-field5,
/var/www/apps/conversion/tmp/scratch_2/261948625.doc
Page 30 of 38
last modification: 2/28/2015
/var/www/apps/conversion/tmp/scratch_2/261948625.doc
Page 31 of 38
last modification: 2/28/2015
ws_struct1 (and ws_struct2) must be the key of the table. But, if several records can have
the same value for the field of the FROM clause, we must write:
Nested LOOP FROM index with several key fields.
Use: Several records can have the same value for the field of the
FROM clause.
DATA: BEGIN OF wt_table1_key,
field1 LIKE table1-field1,
field2 LIKE table2-field2,
field3 LIKE table3-field3,
END OF wt_table1_key.
DATA: BEGIN OF wt_table1 OCCURS
0,
tab1_key LIKE wt_table1_key,
field4 LIKE table4-field4,
field5 LIKE table5-field5,
END OF wt_table1.
DATA: BEGIN OF wt_table2 OCCURS
0,
tab1_key LIKE wt_table1_key,
field6 LIKE table6-field6,
field7 LIKE table7-field7,
/var/www/apps/conversion/tmp/scratch_2/261948625.doc
Page 32 of 38
last modification: 2/28/2015
The index is here memorized in a temporary variable. The variable index is only updated when all
the records having the same value for the field tab1-tab1_key have been processed.
LOOP AT NEW
READ TABLE BINARY SEARCH
Use: No common fields between the tables
SORT wt_table2 BY field.
LOOP AT wt_table1.
AT NEW field1.
CLEAR wt_table2.
READ TABLE wt_table2
WITH KEY field = wt_table1-field2
BINARY SEARCH.
ENDAT.
Treatment.
ENDLOOP.
/var/www/apps/conversion/tmp/scratch_2/261948625.doc
Page 33 of 38
last modification: 2/28/2015
Nested LOOP with a table of <sorted> Type (only up from 4.0 Release)
This method is similar to the previous one. The wt_table2 table being defined as sorted by field1
and field2 fields, the <LOOP WHERE> instruction is optimized in the same way as the <READ
BINARY SEARCH> method. In this case, the coding is easier to read and SAP generates an error if
the table is not correctly sorted.
/var/www/apps/conversion/tmp/scratch_2/261948625.doc
Page 34 of 38
last modification: 2/28/2015
Performance
Deletions and modifications on a table of type <SORTED> are good in term of
performance (as a <READ TABLE BINARY SEARCH>).
But, insertions are very costly because the new records must be correctly positioned so
that the table remains sorted.
So it is not recommended to use this type of table. It is better to use a standard table with
a <READ TABLE BINARY SEARCH> statement for example.
Nested LOOP
with a sorted table
DATA: wt_table2 LIKE SORTED TABLE OF ws_struct
WITH UNIQUE KEY field1 field2
WITH HEADER LINE.
LOOP AT wt_table1.
Treatment.
LOOP AT wt_table2 WHERE field1 = wt_table1-field1.
Treatment.
ENDLOOP.
Treatment.
ENDLOOP.
It is necessary to use the instruction <INSERT TABLE wt_table2> to keep the table
sorted and not to have a duplicate key.
This instruction is more costly than a classical <LOOP MODIFY ENDLOOP> because it
requires a time to maintain the table. This solution is good to use only if lots of data must be
updated in the table.
The READ instruction has a similar coding: READ TABLE wt_table ASSIGNING <fs>.
/var/www/apps/conversion/tmp/scratch_2/261948625.doc
Page 35 of 38
last modification: 2/28/2015
Performance
(1=high, 7=low)
Commentary
LOOP AT wt_table.
PERFORM add1 USING wv_var.
ENDLOOP.
LOOP AT wt_table.
PERFORM add1 USING wv_var.
ENDLOOP.
/var/www/apps/conversion/tmp/scratch_2/261948625.doc
Page 36 of 38
last modification: 2/28/2015
Advantage
The time required to read a hashed table is independent of the number of read records. Therefore
hashed tables are very useful for voluminous tables which are often accessed for reading.
Drawbacks
Example
DATA wt_table TYPE HASHED TABLE OF ws_struct
WITH UNIQUE KEY key
[INITIAL SIZE n] [WITH HEADER LINE]
Performances
The cost of a <SELECT INTO TABLE> is the same with a standard internal table or a hashed table.
But the time for reading a hashed table is less than or equal to the time required for a standard table.
A document is available on this subject:
-
Hashed_tables.doc
10.2. Buffering
Buffering a table is forbidden in most of the cases. However, in some cases and when a good
optimization is important, we can use it. The particular case is the following one:
transparent or pool table,
AND access to the table by reading,
AND a lot of queries to the table,
AND access by primary key (or a part of it),
AND few data updating.
/var/www/apps/conversion/tmp/scratch_2/261948625.doc
Page 37 of 38
last modification: 2/28/2015
general_buffering.doc
single_record_buffering.doc
AxxxTables_buffering.doc
10.3. Indexing
In most of the cases, the creation of an index is not recommended because we must be very careful.
An index can be created when there is no more solution. Each creation must be studied
individually.
The Trace SQL tool permits to check the use of an index.
10.4. PERFORM
The use of <PERFORM> is very important for the program structure. But it is costly. Therefore, if
there are big performance problems, it is advised to avoid using <PERFORM>.
/var/www/apps/conversion/tmp/scratch_2/261948625.doc
Page 38 of 38
last modification: 2/28/2015