Anda di halaman 1dari 11

Declaración de datos:

Se debe evitar el uso de la declaración de campos o variables del tipo tabla-campo,


directamente debe tipificarse por su elemento de datos.

Antes de eliminar algún elemento verificar que no se utilice en otros programas aunque sea
únicamente una referencia.

Las declaraciones de tablas deben ser tipificadas siempre

Types: Begin of ty_Name,

Field type data_element,

Field02 type data_element2,

End of ty_name

Tipo de tabla:

Types: tyt_tabla type table of ty_name.

Tabla Interna

Data: it_tabla type tyt_tabla.

Estructura:

Data: ws_linea type ty_tabla.

La declaración de tabla interna HASHED/SORTED debe ser utilizada para tablas internas que
recibirán un gran volumen de información, sino usar type Standard TABLE .

Información utilizada de SDN de SAP.

La performance en cualquier programa ABAP, depende principalmente del acceso a las bases
de datos. Mientras más se optimice la selección de datos, será mejor la performance.

1. Usar todos los campos claves en la sentencia SELECT o la gran mayoría de los mismos
2. Evitar la sentencia SELECT * utilice solamente los campos que serán necesarios en la
selección de datos .
3. Si coloca todos los campos claves, codificar con un SELECT SINGLE y no un SELECT …
END SELECT. En caso de no contar con todos los campos clave, deberá usar SELECT UP
TO 1 ROWS, si nos interesa únicamente el primer registro.
4. Evitar la sentencia SELECT – ENDSELECT, antes que hacer esto es mejor seleccionar la
información en una tabla interna, y dentro de un loop se puede descartar los registros
que no necesitamos.
5. Se hace lo posible por usas índices para acceder a una tabla, en caso de no existir las
claves por las cuales se accede.
6. Evite usar INTO CORRESPONDING FIELDS de la Tabla. En cambio, mencione
explícitamente los campos, si los campos de la tabla no están en la misma secuencia
que la selección

Gabriela Soria Aguilar Page 1


7. No escriba sentencias SELECT dentro de un LOOP. En lugar de ello, use la opcion FOR
ALL ENTRIES.
Antes de usar la opcion FOR ALL ENTRIES, verificar que:
1. La tabla interna correspondiente no esté vacía. Si la tabla interna está vacía, la
sentencia va a traer TODAS las entradas de la tabla de la base de datos.
2. La tabla interna está ordenada por los campos usados en la cláusula WHERE: Esto
hace más rápida a la selección. (Y borra los duplicados adyacentes por los campos
clave.

Sentencia SELECT anidada.


Evite usar declaraciones SELECT anidadas. En su lugar, haga uso de diferentes tablas internas
para buscar los datos, y use LOOPS anidados para leerlos.

Select Distinct
Siempre que sea posible, evite SELECCIONAR DISTINCIÓN, en su lugar, seleccione datos en la
tabla interna, clasifique y use ELIMINAR DUPLICADOS ADYACENTES.

Uso de OR en cláusula Where


No utilice OR al seleccionar datos de la tabla de base de datos utilizando un índice porque el
optimizador generalmente se detiene si la condición WHERE contiene una expresión OR

e.g.
En lugar de
SELECT *
FROM spfli
WHERE carrid = ‘LH’
AND (cityfrom = ‘FRANKFURT’ OR
city from = ‘NEWYORK’)
Use
SELECT * FROM spfli WHERE (carrid = ‘LH’ AND cityfrom = ‘FRANKFURT’)
OR (carrid = ‘LH’ AND cityfrom = ‘NEWYORK’).

Order By
ORDER BY omitirá el buffer. Por lo tanto, el rendimiento disminuirá. Si desea ordenar datos, es
eficiente ORDENALOS en una tabla interna en lugar de usar ORDER BY. Solo use un ORDER BY
en su SELECT si el orden coincide con el índice, que debe usarse.

Usando la sentencia READ


Al leer un único registro en una tabla interna, el READ TABLE WITH KEY no es una LECTURA
directa. La tabla debe ordenarse por los campos Clave y debe usarse el comando READ TABLE
WITH KEY BINARY SEARCH; de lo contrario, la tabla se leerá de arriba abajo hasta que se

Gabriela Soria Aguilar Page 2


encuentre un campo que coincida con la CLAVE.
When reading a single record in an internal table, the READ TABLE WITH KEY is not a direct
READ. The table needs to be sorted by the Key fields and the command READ TABLE WITH KEY
BINARY SEARCH is to be used; otherwise the table is read from top to bottom until a field
matching the KEY is found.

Append Lines of
Whenever it is possible use APPEND LINES OF to append the internal Tables instead of using
loop and then APPEND Statement.

DELETE <itab> WHERE


Use DELETE <itab> WHERE…for deleting records from an internal table.
e.g.
Instead of
LOOP AT <itab> WHERE <field> = ‘0001’
DELETE <itab>.
ENDLOOP.
Use
DELETE <itab> WHERE <field> = ‘0001’.

Using WHERE clause in LOOP…….ENDLOOP


Use:
Loop at itab where name EQ SY-UNAME
..
Endloop.
Instead Of:
Loop at itab from l_tabix.
If name = SY-UNAME.
Endif.
Endloop.

Subroutine Usage
For good modularization, the decision of whether or not to execute a subroutine should be
made before the subroutine is called.
Example:
IF f1 NE 0.
PERFORM sub1.

Gabriela Soria Aguilar Page 3


ENDIF.
FORM sub1.
...
ENDFORM.

Case vs. Nested IF


When testing fields "equal to" something, one can use either the nested IF or the CASE
statement. The CASE is better for two reasons. It is easier to read and after about five nested
IFs the performance of the CASE is more efficient.

Hashed table
If the number of entries in the Internal Table is high then use Hashed Table with Keys to access
the table.

Transporting
With READ or MODIFY Statements use TRANSPORTING and specify the fields being
transported.
( Modifying internal table its best to use field symbol )

Using LDB
In order to improve performance in case of an LDB, individual tables can be excluded from
selection. Under the section ‘Table Selection’ in the Documentation of LDB the fields with
proper description has been given those fields can be set in the application report at the time
of INITIALIZATION or at the START OF SELECTION. This can enhance the performance.

Use WHILE
Use WHILE instead of a DO+EXIT-construction, as WHILE is easier to understand and faster to
execute

Identical Structures
If two structures are identical, use MOVE x to y, rather than MOVE-CORRESPONDING x to y
When records a and b have the exact same structure, it is more efficient to MOVE a TO b than
to MOVE-CORRESPONDING a TO b.
MOVE BSEG TO *BSEG.
is better than
MOVE-CORRESPONDING BSEG TO *BSEG.

Gabriela Soria Aguilar Page 4


Order of tests
*Ensure that the first tested condition in an IF statement is most frequently true. For a logical
AND statement put the most likely FALSE case first, and conversely for a logical OR statement
put the most likely TRUE statement first. (But this will only lead to a noticeable performance
improvement if the test is performed *very many times with a loop.

Nested loop
Ensure that instead of nested loop, parallel cursor method is used wherever possible. Parallel
cursor method involves finding out the index using READ statement & searching only the
relevant entries. This will give huge performance benefits. And if possible, RFC parallelization
method can also be considered.
Nested loop
Loop at T1 into W1.
Loop at T2 into W2 where F1 = W1-F1.
Endloop
Endloop
Parallel cursor method
Loop at T1 into W1.
Read table T2 into W2 with key F1 = W1-F1 Binary Search.
l_index = SY-tabix.
Loop at T2 into W3 from l_index.
If W3-F1 <> W1-F1.
Exit. “ Exit inner loop when condition fails
Endif.
Endloop
Endloop
Use Parallel Cursor methods for nested loop into the internal tables if second internal table
contains considerable number of records.

Inner joins Vs For all Entries-FAE


In most cases, INNER JOIN is better performing than FAE, so it should be used first.
The set of data that can be selected with a view greatly depends on whether the view
implements an inner join or an outer join. With an inner join, you only get those records which
have an entry in all the tables included in the view. With an outer join, on the other hand,
those records that do not have a corresponding entry in some of the tables included in the
view are also selected.
The hit list found with an inner join can therefore be a subset of the hit list found with an outer
join. Database views implement an inner join. You only get those records which have an entry

Gabriela Soria Aguilar Page 5


in all the tables included in the view. Help views and maintenance views, however, implement
an outer join. So basically it tells us that we have to choose the join based on the requirement.
And “FOR ALL ENTRIES-FAE” should be avoided in case a large Volume of Data is expected in
the Driver Internal Table, because the Single Database Process might starts eating the System
resources more than what is top limit set by the BASIS people and hence we might end up with
a Short Dump. In this kind of Cases, prefer using Inner Joins over For All Entries.
we need to check the parent table is empty or not. if its empty then 2nd table will retrieve all
data.

Index tables
Try to make use of INDEX tables as much as possible to improve the performance.
e.g.: If data needs to be fetched from VBAP table based on Material number which is not a key
field, prior looking for a secondary index with material, try to find whether any INDEX TABLE
exists. In this case VAPMA is an index table which will return the SD Document number and
item where a material exists.
Note: In all the cases Index table may not exists and even if Index table exists make sure its
active. i.e. the index table contains approximately the same no entries compared to the main
table

Usage of cursors over Select…INTO/Select..Endselect


Cursor is a control structure for successive traversal through data. The rows in the result set
will be processed sequentially by the application. Cursor acts as an iterator over a collection of
rows in the result set.
Fetching data from the Database
Data is fetched from the database depending on the data specified in the SELECT statement
along with its additions. There are two core operations to get the data from the database.

 OPEN / RE-OPEN.
 FETCH.

OPEN / RE-OPEN: This is the process to start or to flag-off the process of getting data from the
database. This is like a green signal of the traffic lights that denotes that it is the time to get
the data from the source location.
FETCH: This locates the database data that satisfies the conditions and then transfers it into
the Application Server. The data is transferred in one or more Fetches; it is called an Array
Fetch. An Array Fetch offers better performance than transferring data in the form of single
records in Client/Server architecture.
Maximum number of records that can be Fetched in an operation is determined by the SAP DB
interface.
The default value that is set by the SAP for this purpose is 33,792 bytes.
from application system to presentation system also fixed. But we can change that value.

Performance diagnosis

Gabriela Soria Aguilar Page 6


To diagnose performance problems, it is recommended to use the SAP transaction SE30,
ABAP/4 Runtime Analysis. The utility allows statistical analysis of transactions and programs.

SQL Trace
Use transaction ST05 (SQL Trace) to see what indices your database accesses are using. Check
these indices against your “where” clause to assure they are significant. Check other indices
for this table and where you have to change your “where” clause to use it.

Gabriela Soria Aguilar Page 7


What tools can be used to help with performance tuning?
ST05 is the performance trace. It contain the SQL Trace plus RFC, enqueue and buffer trace.
Mainly the SQL trace is is used to measure the performance of the select statements of the
program.
SE30 is the Runtime Analysis transaction and can be used to measure the application
performance.
SAT transaction is the replacement of the pretty outdated SE30. Provides same functionality as
SE30 plus some additional features.
ST12 transaction (part of ST-A/PI software component) is a combination of ST05 and SAT. Very
powerful performance analysis tool used primarily by SAP Support.
One of the best tools for static performance analyzing is Code Inspector (SCI). There are many
options for finding common mistakes and possible performance bottlenecks.
back to top

What are the steps to optimize the ABAP Code?

1. DATABASE
a. Use WHERE clause in your SELECT statement to restrict the volume of data retrieved. Very
important !!
b. Design your Query to Use as much index fields as possible in your WHERE statement
c. Use INNER (or OUTER under some circumstances) JOIN in your SELECT statement to retrieve
the matching records at one shot
d. Avoid using nested SELECT statement and SELECT within LOOPs, better use JOINs or FOR ALL
ENTRIES. Use FOR ALL ENTRIES when the internal table is already there or the end of some
processing. Try JOINs if the SELECT are right behind each other
e. Avoid using INTO CORRESPONDING FIELDS OF TABLE during buffered access. Otherwise use
the most appropriate for the program.
f. Avoid using SELECT * and Select only the required fields from the table.
g. Avoid using ORDER BY in SELECT statements if it differs from used index (instead, sort the
resulting internal table), because this may add additional work to the database system which is
unique, while there may be many ABAP servers
h. INDEX: Creation of Index for improving performance should not be taken without thought.
Index speeds up the performance but at the same time adds two overheads namely; memory
and insert/append performance. When INDEX is created, memory is used up for storing the
index and index sizes can be quite big on large transaction tables! When inserting new entry in
the table, all the index's are updated. More index more time. More the amount of data, bigger
the indices, larger the time for updating all the indices
i. Avoid Executing an identical Select (same SELECT, same parameter) multiple times in the
program. Buffer in your abap code.
j. Avoid using join statements if adequate standard views exist no performance impact
2. TABLE BUFFER:
a. Defining a table as buffered (SE11) can help in improving the performance but this has to be
used with caution. Buffering of tables leads to data being read from the buffer rather than
from table. Buffer sync with table happens periodically, only if something changes which is
happen rarely. If this table is a transaction table chances are that the data is changing for a
particular selection criteria, therefore application tables are usually not suited for table
bufferung. Using table buffering in such cases is not recommended. Use Table Buffering for
configuration data and sometimes for Master Data..

Gabriela Soria Aguilar Page 8


b. Avoid using complex Selects on buffered tables-, because SAP may not be able to interpret this
request, and may transmit the request to the database- The code inspector tells which
commands bypass the buffer
3. Internal tables
a. Use HASHED tables where-ever possible. Otherwise SORTED tables. STANDARD tables should
be the last choice.
b. Use assign instead of into in LOOPs for table types with large work areas, if the data is being
modified.
c. When in doubt call transaction SE30 and check your code.
d. If you must use a STANDARD table and you are using a READ, sort the table appropriately and
use the addition BINARY SEARCH to speed up the search.
4. Miscellaneous
a. PERFORM : When writing a subroutine, always provide type for all the parameters. This
reduces the overhead which is present when system determines on it's own each type from
the formal parameters that are passed. It also makes for more robust programming.

What is the difference between SELECT SINGLE and SELECT ... UP TO 1 ROWS?

 SELECT SINGLE and SELECT UP TO n ROWS return the first matching row/rows for the given
condition. It may not be unique, if there are more matching rows for the given condition.
 With ORACLE database system, SELECT SINGLE is converted into SELECT ... UP TO 1 ROWS, thus
they are exactly the same in that case. The only difference is the ABAP syntax prevents from
using ORDER BY with SELECT SINGLE, but it is allowed with SELECT ... UP TO 1 ROWS. Thus, if
several records may be returned and we want to get the highest record for example, SELECT
SINGLE cannot be used, but SELECT ... UP TO 1 ROWS WHERE ... ORDER BY ... may be used.

Which is the better - JOINS or SELECT... FOR ALL ENTRIES...?


In most scenarios INNER JOIN performs better than FOR ALL ENTRIES, and should be used first.
Only if there are performance issues should FOR ALL ENTRIES be considered, and careful
measurements taken before and after to validate whether there really are performance gains.
The effect of FOR ALL ENTRIES needs to be observed first by running a test program and
analyzing SQL trace. Certain options set by BASIS can cause FOR ALL ENTRIES to execute as an
'OR' condition. This means if the table being used FOR ALL ENTRIES has 3 records, SQL Trace
will show 3 SQL's getting executed. In such a case using FOR ALL ENTRIES is useless. However
of the SQL Trace shows 1 SQL statement it's beneficial since in this case FOR ALL ENTRIES is
actually getting executed as an IN List.
JOINS are recommended over FOR ALL ENTRIES. There is no real limit to the number of tables
that can be joined; however greater complexity can make maintenance harder, and if there are
problems with the join, make it harder to resolve them. If the JOIN is being made on fields
which are key fields in both the tables, it reduced program overhead and increases
performance.
In some scenarios, you are presented with an internal table. In these situations, you may have
no choice but to use FOR ALL ENTRIES.
Here is a code with join :
Error al representar macro 'code': Valor inválido especificado para parámetro 'lang'

SELECT A~VBELN A~KUNNR A~KUNAG B~NAME1


INTO TABLE I_LIKP

Gabriela Soria Aguilar Page 9


FROM LIKP AS A
INNER JOIN KNA1 AS B
ON A~KUNNR = B~KUNNR.
* For with limited data using for all entries:
* Minimize entries in I_likp by deleting duplicate kunnr.
LOOP AT I_LIKP INTO W_LIKP.
W_LIKP2-KUNAG = W_LIKP-KUNAG.
APPEND W_LIKP2 TO I_LIKP2.
ENDLOOP.
SORT I_LIKP2 BY KUNNR.
DELETE ADJACENT DUPLICATES FROM I_LIKP2 COMPARING KUNNR.
* GET DATA FROM kna1
IF NOT I_LIKP2[] IS INITIAL.
SELECT KUNNR NAME1
INTO TABLE I_KNA1
FROM KNA1
FOR ALL ENTRIES IN I_LIKP2
WHERE KUNNR = I_LIKP2-KUNNR.
ENDIF.

User Collect Statement to do Sum in the internal table.

Instead of using logic to do summation use collect statement. COLLECT is especially efficient
with HASHED tables.

Avoid use of nested loops


For example: if there is a loop like this. Condition added, otherwise there is no optimization:
Error al representar macro 'code': Valor inválido especificado para parámetro 'lang'

LOOP AT ITAB1.

LOOP AT ITAB2 WHERE F1 = ITAB1-F1.

....

ENDLOOP.

Gabriela Soria Aguilar Page 10


END LOOP.
in the production environment it may be possible that such a loop takes a lot of time and
dumps.
Instead we can use ... BINARY SEARCH added, otherwise no improvement!!! Better still - use a
HASHED or SORT TABLE.
Error al representar macro 'code': Valor inválido especificado para parámetro 'lang'

SORT ITAB2 BY F1.


LOOP AT ITAB1.
READ TABLE ITAB2 WITH KEY F1 = ITAB1- BINARY SEARCH. "f1 is any field of itab1
IF SY-SUBRC = 0.
IDX = SY-TABIX.
LOOP AT ITAB2 FROM IDX.
IF ITAB2-F1 <> ITAB1-F1.
EXIT.
ENDIF.
....
ENDLOOP.
ENDIF.
ENDLOOP.
If you have a sorted table - the internal table can be read like this:
Error al representar macro 'code': Valor inválido especificado para parámetro 'lang'

TYPES: BEGIN OF ITAB,


F1 TYPE MARA-MATNR,
....
*NOT ONLY THE KEYFIELD !!
END OF ITAB.
DATA: ITAB2 TYPE SORTED TABLE OF ITAB WITH UNIQUE KEY F1.
LOOP AT ITAB1.
LOOP AT IATB2 WHERE F1 = ITAB1. "f1 is any field of itab1
....
ENDLOOP.
ENDLOOP.

Gabriela Soria Aguilar Page 11

Anda mungkin juga menyukai