Professional Documents
Culture Documents
ABAP Performance and Best Practices A Bible V1 0
ABAP Performance and Best Practices A Bible V1 0
ABAP Performance and Best Practices A Bible V1 0
Page 1
Symbols used :
Symbol
Meaning
Not the best method (to be used only when there is no other way).
Additional information .
Page 2
Write a program accurately which will be more performing in its execution time and would not break in real time?
Page 3
Goals :
Explore the areas of performance tuning in ABAP . Write fine tuned new ABAP programs . Fine tune existing ABAP programs .
Page 4
General Rules. Selection on a single table . Selection on many tables . Commit and Rollback . Data Dictionary . Mass treatment Internal table and data base . Operations on internal tables . Special topics . Tools available to validate source code from performance and standards point of view. Tools available to measure performance.
Page 5
Page 6
Avoid NULL statements (statements without effect) Avoid deeply nested loops Avoid unreachable program parts Avoid side-effects on global variables Do not use a variable for multiple purposes (e.g. as counter and as string) Avoid spaghetti code .
Page 7
General rules :
When we use the <SELECT INTO TABLE wt_table> instruction, exchanges between the database server and the application server are made by packets. When we use the <SELECT ENDSELECT> instruction, exchanges between the database server and the application server are one recording by one recording.
Page 8
General rules :
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
Page 9
General rules :
Queries
Queries are forbidden because programs generated by a Query are not performing at all. Requests are not optimized, thus execution time is too high.
Page 10
SELECT SINGLE * FROM table WHERE field1 = xxx. IF sy-subrc = 0. Treatment. ENDIF.
After many compared tests, it is proven that the <SELECT SINGLE> instruction seems to be more efficient that <UP TO 1 ROWS> one.
Page 11
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.
0.8
SELECT SINGLE field1 INTO table-field1 FROM table WHERE field2 = xxx.
Page 12
The order of the fields in the <WHERE> clause has an impact on the execution time of the request. SAP works with a positioning pointer on the tables. The first field of the <WHERE> clause permits the pointer to position itself. Then the table is sequentially read. Therefore the order of the tests in the <WHERE> clause is very important.
When the developer codes an instruction in order to read in the database, he/she must respect the following rules by ascending priority: Put the fields in the same order of the existing index (primary or secondary). Put the fields in the same order of the key .
Runtime chooses the index based on the fields used in <where> clause. Order of the fields in <where> clause is very important in deciding index.
Page 13
Primary
Fields forming the primary key of the table form primary index. Every table has a primary index by default. Created automatically when the table is activated . As far as possible , primary index should be used . Consists of fields from non primary keys. When the primary index cannot be used , secondary indexes have to be created explicitely . When the table is client dependent , the secondary index must contain MANDT as first field . Slows related SAP transactions . Fields in the <where> clause doesnot form fields from any index .
Secondary
No Index
Page 14
Page 15
Data sorting Sorting on the database server. Sorting on the application server.
SELECT * FROM table WHERE field1 = xxxx ORDER BY field2. Treatment. EXIT. ENDSELECT.
SELECT * INTO TABLE wt_table FROM table WHERE field1 = xxxx. IF sy-dbcnt NE 0. SORT wt_table BY field2. LOOP AT wt_table. Treatment. ENDLOOP. ENDIF.
Page 16
SELECT SINGLE * INTO table FROM table WHERE field1 = xxxx. IF sy-dbcnt NE 0. wv_field2 = table-field2. Treatment. ENDIF.
SELECT SINGLE field2 INTO wv_field2 FROM table WHERE field1 = xxxx IF sy-dbcnt NE 0. Treatment. ENDIF.
Page 17
<APPENDING TABLE> option : This option permits to add further records to an internal specified table. The <APPEND> instruction is included is the <APPENDING TABLE> instruction. If the internal table is refreshed (<REFRESH>) just before using the <APPENDING TABLE> instruction, it is the same as using the <INTO TABLE> instruction. Therefore if the internal table is empty, the <APPENDING TABLE> instruction must not be used. There is no <ENDSELECT> instruction because it is not a loop treatment. The updating of the table is carried out at one go.
Page 18
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.
Page 19
SELECT SINGLE * INTO CORRESPONDING FIELDS OF table FROM table WHERE key = xxxx. 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.
SELECT SINGLE * FROM table WHERE key = xxx. DATA : BEGIN OF ws_struct, field1 LIKE table-field1, field2 LIKE table-field2, field3 LIKE table-field3, END OF ws_struct. SELECT SINGLE field1 field2 field3 INTO ws_struct FROM table WHERE field1 = xxxx.
Page 20
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.
Page 21
DATA : BEGIN OF wt_table OCCURS 0, field1 LIKE table-field1, field2 LIKE table-field2, field3 LIKE table-field3, END OF wt_table. SELECT field1 field2 field3 INTO TABLE wt_table FROM table WHERE field1 = xxxx.
SELECT field1 field2 field3 INTO TABLE wt_table FROM table WHERE field1 = xxxx.
Page 22
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.
Page 24
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.
Page 25
SELECT * FROM table INTO TABLE wt_table WHERE field IN ( SELECT FROM WHERE).
Page 26
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.
Page 27
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.
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.
Page 28
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.
Page 30
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. 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. 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.
Page 31
Using recommendations :
Type of selection on many tables Using recommendat ions (1=high, 6=low) 1 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 duplicates. Use it when there is a 1 to n relation on the key. Use the views created by SAP. Avoid creating new specifics views. Not recommended. Forbidden. Forbidden.
2 3 4 5 6
Page 32
DELETE FROM y9nav WHERE zznom OR zzpavillon NE space. IF sy-subrc NE 0. ROLLBACK WORK. EXIT. ENDIF.
NE space
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 sy-subrc 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.
Page 33
Data dictionary: Table creation Summary of the parameters for a specific table
Question Delivery class Do we wish to update the table in production only by transport? Does the modification of the table need obligatory integration tests? Table maintenance Must the table be manually modified? Is it possible to use the SM30/SM31 transaction to maintain it? Is the table of delivery class C? Tick authorized SM30/SM31 box and generate the table maintenance Data type APPL2 Specific program Yes Delivery class C No Delivery class A
Data Type
See the following question. Data type APPL0 Key the corresponding size category between 0 and 4.
Is the table often modified? Table category Is the size of the table in production uncertain?
Data type APPL1 Choose a category with a size greater than those of the forecast
Page 34
Data dictionary: Table creation Summary of the parameters for a specific table
Question Buffering Is the table often read by transactions? Is the table rarely modified ? Is the table use buffering? Is the table small? Is the number of readings high? Is the number of writings small? Is the table large? Are few different recordings read? Is the table always read with the same beginning of key (language code, company, analytical perimeter, country code)? Log data changes Is the volume of creations/modifications is small? Is it important to know who and when a table has been modified? Is it important to be able to restitute the table contents at a given date?
Page 35
Proprietary and confidential Copyright Capgemini 2007 All Rights Reserved
Page 36
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>.
Page 37
Case 1: The comparison in the <WHERE> clause is made with a constant Deletion record by record. Mass deletion
SELECT * FROM table WHERE field1 = wc_const. IF sy-subrc = 0. DELETE table. ENDIF. ENDSELECT.
Page 38
LOOP AT wt_table. SELECT * FROM table WHERE field1 = wt_table-field1. IF sy-subrc = 0. DELETE table. ENDIF. ENDSELECT. ENDLOOP.
Page 39
Mass correction
LOOP AT wt_table WHERE field1 = xxx. wt_table-field2 = aaa. wt_table-field3 = bbb. MODIFY wt_table. ENDLOOP.
CLEAR wt_table. wt_table-field2 = aaa. wt_table-field3 = bbb. MODIFY wt_table TRANSPORTING field2 field3 WHERE field1 = xxx.
Page 40
SELECT * FROM table WHERE field3 = wc_const field1 = wc_const1. field2 = wc_const2. MODIFY table. ENSELECT.
Update 1. 2. 3. Faster. Doesnot make any check before update . Results into dump if record to be modified is not found in DB.
Modify 1. 2. 3. Slow. Makes a check before update. If record doesnot exist in DB , it will insert a record .
Page 41
LOOP AT wt_table_tmp. CLEAR wt_table. wt_table-field1 = wt_table_tmp-field4. wt_table-field2 = wt_table_tmp-field5. APPEND wt_table. ENDLOOP. DESCRIBE TABLE wt_table. IF sy-tfill NE 0. SORT wt_table BY field1. DELETE ADJACENT DUPLICATES FROM wt_table COMPARING field1. MODIFY table FROM TABLE wt_table. ENDIF.
Page 42
WBEI Engagement Overview
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.
Page 43
- Storage of the data for insertion in an internal table - Insertion of the data into the transparent table thanks to the internal table. LOOP treatment. wt_table-field1 = . wt_table-field2 = . APPEND wt_table. ENDLOOP. SORT wt_table BY field1 . DELETE ADJACENT DUPLICATES FROM wt_table COMPARING field1. INSERT table FROM TABLE wt_table.
Page 44
Sequential data research. Forbidden except in the case of a small internal table READ TABLE wt_table WITH KEY field1 = wv_field1.
SORT wt_table BY field1. READ TABLE wt_table WITH KEY field1 = wv_field1 BINARY SEARCH.
Page 45
<READ TABLE> without <BINARY SEARCH> LOOP AT wt_table1. (or loop from index, loop where, do) Treatment. READ TABLE wt_table2 WITH KEY key. IF sy-subrc = 0. Treatment1. MODIFY wt_table2 INDEX sy-tabix. ELSE. Treatment2. APPEND wt_table2. ENDIF. Treatment. ENDLOOP.
LOOP AT wt_table1. (or loop from index, loop where, do) Treatment. SORT wt_table2 BY key. READ TABLE wt_table2 WITH KEY key BINARY SEARCH. IF sy-subrc = 0. Treatment1. MODIFY wt_table2 INDEX sy-tabix. ELSE. Treatment2. APPEND wt_table2. ENDIF. Treatment. ENDLOOP.
Page 46
WBEI Engagement Overview
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.
Page 47
Loop : Control break statement. Control breaks The instructions between <AT > and <ENDAT> are executed only:
AT FIRST
AT LAST AT NEW AT END OF
Page 48
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>.
Page 49
Nested loops.
LOOP AT wt_table1. LOOP AT wt_table2 WHERE field = wt_table1-field. Treatment. ENDLOOP. ENDLOOP.
Page 50
DATA: BEGIN OF wt_table1 OCCURS 0, field1 LIKE wt_table1_key, field4 LIKE table4-field4, field5 LIKE table5-field5, END OF wt_table1. DATA: BEGIN OF wt_table2 OCCURS 0, field1 LIKE wt_table1_key, field6 LIKE table6-field6, field7 LIKE table7-field7, field8 LIKE table8-field8, END OF wt_table2.
Page 51
Nested LOOP FROM index with several key-fields(Parallel cursor). Use1 : ws_struct1 and ws_struct2 form the key for search
and there are unique entries with this combination in itab2.
Nested LOOP FROM index with several key fields . Principle : Donot read the entire second itab . Remember the last position read . Must condition : Sort on itab1 and itab2 should be on same fields .
DATA: BEGIN OF wt_table1, field1 LIKE , field2 LIKE , field3 LIKE , field4 LIKE , field5 LIKE , field6 LIKE , END OF wt_table1. DATA: BEGIN OF wt_table2, field1 LIKE , field2 LIKE , field3 LIKE , field4 LIKE , field5 LIKE , field6 LIKE , END OF wt_table2.
SORT wt_table1 BY field2 field4 field6. SORT wt_table2 BY field2 field4 field6. wv_index = 1. LOOP AT wt_table1. ws_struct1-field1 = field2. ws_struct1-field2 = field4. ws_struct1-field3 = field6. LOOP AT wt_table2 FROM wv_index. ws_struct2-field1 = field2. ws_struct2-field2 = field4. ws_struct2-field3 = field6. IF ws_struct1 = ws_struct2. Treatment. ELSEIF ws_struct2 > ws_struct1. wv_index = sy-tabix. Exit. ENDIF. ENDLOOP. ENDLOOP.
DATA: BEGIN OF ws_struct1, field1 LIKE wt_table1-field2, field2 LIKE wt_table1-field4, field3 LIKE wt_table1-field6, END OF ws_struct1. DATA: BEGIN OF ws_struct2, field1 LIKE wt_table2-field2, field2 LIKE wt_table2-field4, field3 LIKE wt_table2-field6, END OF ws_struct2.
Page 52
Nested LOOP FROM index with several key fields. Use2 : Refering to last slide , 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. Must condition : Sort on itab1 and itab2 should be on same fields . 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, field8 LIKE table8-field8, END OF wt_table2. SORT wt_table1 BY tab1_key. SORT wt_table2 BY tab1_key. wv_index = 1. LOOP AT wt_table1. Treatment. LOOP AT wt_table2 FROM wv_index. IF wt_table2-tab1_key = wt_table1-tab1_key. Treatment. ELSEIF wt_table2-tab1_key > wt_table1-tab1_key. wv_index_tmp = sy-tabix. EXIT. ENDIF. ENDLOOP. AT END OF tab1_key. wv_index = wv_index_tmp. ENDAT. Treatment. The index is here memorized in a ENDLOOP.
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.
Page 53
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. 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.
It is necessary to use the instruction <INSERT TABLE wt_table2> to keep the table sorted and not to have a duplicate key. Append table can lead to short dump.
Page 55
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>.
Page 56
The execution time is proportional to the number of records processed. Use: one field composes the common key of the tables. Use: several fields compose the common key of the two tables. Use: A table cannot be sorted.
Nested LOOP with several key fields Nested LOOP with READ TABLE BINARY SEARCH LOOP AT NEW READ TABLE BINARY SEARCH Nested LOOP WHERE with SORTED TABLE Nested LOOP WHERE Basic Nested LOOP
The table is defined as a sorted table. Not recommended. The execution time is exponential to the number of records processed. Forbidden. Forbidden.
WBEI Engagement Overview
6 7
Page 57
Form/ Perform:
The use of <FORM> enables to organize the program to make it more readable, easier to maintain, with appropriate names easier to understand. The <FORM> instruction permits to add on parameters during the function call. A parameter is a variable. Therefore the conversion is important. That is why, if a <FORM> is used and has parameters, it is advised to standardize the different parameters as often as possible in order to avoid the conversions that are very costly in time for the SAP processor. The <ANY> type is not a real type.
DATA: wv_var TYPE i. LOOP AT wt_table. PERFORM add1 USING wv_var. ENDLOOP. FORM add1 USING param. ADD 1 TO param. Treatment. ENDFORM.
DATA: wv_var TYPE i. LOOP AT wt_table. PERFORM add1 USING wv_var. ENDLOOP. FORM add1 USING param TYPE i. ADD 1 TO param. Treatment. ENDFORM.
Page 58
-> Define sufficient exceptions in function modules and raise them as needed. -> In the calling program handle all the exceptions . ->If no exceptions are available in function module , still handle the others exception .
->Exceptions when raised , if not handled in calling program result in short dump .
Page 59
Special topics:
1. Hashed tables. 2. Buffering.
3. Indexing.
4. PERFORM. 5. Parallel processing. 6. Aggregate functions.
Page 60
Hashed tables:
Principle : The access to a hashed table is only made by a unique key thanks to a hashed algorithm. 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. Sorting a hashed table is impossible. The key must be complete when we do a research. The reading of a hashed table is carried out by the <READ TABLE wt_table WITH TABLE KEY>. A hashed table is quick in reading; otherwise there is a not lot of uses. It is impossible to read/ insert/ modify a record in a hashed table by using an index. Example DATA wt_table TYPE HASHED TABLE OF ws_struct WITH UNIQUE KEY key [INITIAL SIZE n] [WITH HEADER LINE] 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.
Page 61
Buffering :
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: 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. -> Usually customizing tables are buffered. Transparent tables are prone to frequent changes and master data tables are huge in size to be buffered. -> Should not be buffered if secondary index exists on the table. -> Table should not appear in a view if buffering is allowed.
Page 62
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.
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>. In general PERFORM increases readability of source code and is good to use.
Page 63
Parallel processing :
Call function STARTING NEW TASK DESTINATION IN GROUP allocates the processing to a new Dialog task. So the entire data processing can be split into different dialog tasks . Messages received back from task could be processed via a subroutine in calling program. Faster processing compared to serial processing as it uses asynchronous processing . As the processing happens in a dialog work process which has a auto logout time limitation. Will cause problem if there is a dependency between the data which is processed in two different dialog tasks. FM should be RFC enabled. The calling program should not change to a new internal session after making an asynchronous RFC call. That is, you should not use SUBMIT or CALL TRANSACTION in such a report after using CALL FUNCTION STARTING NEW TASK. Server must have atleast 3 dialog work processes. Dispatcher queue less than 10% full, at least one dialog work process free for processing tasks from the parallel job.
Concept
Advantages Disadvantages
Prerequisites
Page 64
start-of-selection.
call function 'BAPI_CUSTOMER_GETDETAIL2' starting new task 'FUNC1' destination 'NONE' performing set_function1_done on end of task exporting customerno = p_kunnr.
**************************************************** **** * FORM FUNCTION1_DONE **************************************************** **** form set_function1_done using taskname.
receive results from function 'BAPI_CUSTOMER_GETDETAIL2' importing customergeneraldetail = cstgdetail1. functioncall1 = done. endform.
Page 65
Advantage
Data fetched from database to ABAP layer is less . Aggregation is done on Database level. So no further treatment is necessary on ABAP layer. Reduces coding effort . Reduces performance as aggregation is done at database level.
Disadvantage
To be avoided when data records that are worked upon in aggregate functions are big in number.
Page 66
Page 67
Page 68
Page 69
Page 70
Tools available to measure performance : Run time analysis : SE30 (ABAP V/S Database)
Page 71
Page 72
Page 73
Page 74
Page 75
Page 76
Page 77