Documentación -Código fuente -Contacto -Empleo

Buscar

Buscar

Traducir

Login



Eficiencia en ABAP
Eficiencia en ABAP PDF Imprimir Correo
Usar puntuación: / 2
MaloBueno 
Documentación - Manuales breves
Jueves, 30 de Junio de 2005 16:36

1.2 Recomendaciones Generales





1.2.1 Consideraciones SAP- ABAP





  • No actualizar NUNCA la base de datos directamente mediante funciones no desarrolladas u originales de SAP. Es decir, no utilizar nunca explícitamente las instrucciones INSERT, UPDATE, MODIFY o DELETE sobre tablas estándar de SAP. Deben utilizarse los procedimientos de actualización previstos por SAP como batch-input, direct input o call transaction.



  • En el caso de tener desarrollos propios que incluyan definición de tablas propias que crecen con el tiempo, tener previsto siempre la posibilidad de realizar un archivado de los datos propios o en su defecto, eliminación de datos obsoletos que no interesa seguir teniendo en el sistema. (Nota: No es aconsejable acceder a datos de transacción sólo con datos maestros –por ejemplo a pedidos de la tabla VBAK sólo con el número de cliente-, ya que siempre cogeremos más registros de los deseados. Conviene usar más campos –por ejemplo la fecha- para limitar el resultado.



  • En el caso de utilizar programas externos a SAP, como servidores RFC o clientes RFC tener en consideración al posibilidad de realizar balanceo de carga



  • Tener en cuenta la concurrencia de accesos si se realizan programas para actualizar tablas propias definidas por el cliente mediante la utilización de objetos de bloqueo.



  • Los accesos a la base de datos deben evitar el realizar un 'Full Table scan' de la misma. La programación de la cláusulas de acceso a la base de datos siempre deben estar basadas en índices, o en casos especiales de conveniencia, realizar una lectura secuencial de la tabla. Pero si se quiere acceder por índice hay que indicar en el predicado de la cláusula todos los campos del índice conocidos por el programa. Por ejemplo: la tabla VBAK definida con los campos: MANDT BELNR POSNR ..., y tiene un índice primario construido así: MANDT, BELNR y POSNR; si en la cláusula WHERE no contiene el campo BELNR, la BD no puede usará el índice adecuadamente.



  • El conjunto de instrucciones con SQL nativo o EXEC-SQL no es conveniente de forma general ya que:

    • No utilizan los buffers intermedios de SAP

    • Pueden hacer la programación dependiente del gestor de base de datos que se utilice.

    • En ocasiones puede ser la única alternativa en caso de tener que acceder desde un ABAP a una base de datos externa no-SAP, (por ejemplo acceso a una base de datos Oracle en NT mediante ODBC).



  • Al codificar bucles, diseñarlos de forma que las condiciones que más frecuentemente sean verdaderas ocupen los niveles exteriores del bucle.



  • Para expresiones o evaluaciones lógicas que incluyan el operador AND, situar la condición que más frecuentemente sea falsa en primer lugar.



  • Tener identificados de la manera más precisa y operativa posible cuáles son los procesos que no deben ser ejecutados en concurrencia con el online o con los momentos de mayor actividad online en el sistema. A modo de ejemplo normalmente la ejecución de programas que realicen CALL TRANSACTION de forma masiva o lanzamiento de batch-inputs debe estar limitada cuando se procesen de forma concurrente con el on-line.



1.2.2 Normas generales para programación SQL





Basándonos en la arquitectura de los sistemas R/3, existen unas normas básicas y fundamentales que es necesario aplicar en programación ABAP para que los accesos a las BD sean eficientes. Son los siguientes:



  • Conseguir un conjunto de respuestas pequeño.



  • Esto reduce: tanto la cantidad de memoria utilizada por el DBMS como la carga de la red cuando se transfieren los datos al servidor de aplicación. Por ejemplo no usar select anidados sino JOINS o VISTAS.



  • Minimizar la cantidad de datos a transferir



  • Restringir el número de líneas.

  • Restringir el número de columnas.

  • Usar funciones globales (sum, average, minimun, ...) cuando los datos a usar sean sólo para cálculos.

  • Transferir los datos exactos cuando se cambien líneas de una tabla. Con la sentencia UPDATE para cambiar líneas, se debería usar la cláusula WHERE para especificar las líneas relevantes y la sentencia SET para cambiar sólo las columnas necesarias.



  • Minimizar el número de transferencias de datos



  • Conviene reducir la carga de la red y del servidor de la BD minimizando el número de veces que se accede a la BD:

  • Evitar accesos repetidos.

  • Evitar bucles SELECT anidados.

  • Usar Views y Joins.

  • Evitar sub-preguntas en las cláusulas WHERE y HAVING.

  • Usar tablas internas en bucles SELECT.

  • Usar un cursor para leer los datos. Este nuevo método se basa en evitar la cláusula INTO de la sentencia SELECT utilizando un cursor (OPEN CURSOR) y leyendo los datos línea a línea (FETCH NEXT CURSOR). Es necesario abrir un nuevo cursor en cada paso del bucle.



  • Minimizar el tiempo de búsqueda



  • Formular condiciones de búsqueda por índices.

  • Utilizar condiciones positivas (por ejemplo EQ y LIKE) en vez de negativas (NE y NOT LIKE). Evitar el operador NOT.

  • No chequear por valores nulos (NULL).

  • No usar parte de un índice: al construir un índice de varias columnas el sistema puede usarlo aunque sólo se especifiquen unas pocas columnas en la condición. La secuencia de las columnas en el índice es importante. Una columna sólo podrá usarse en la consulta por índice si todas las columnas anteriores (en la definición del índice) se han especificado también en la condición de búsqueda.

  • Evitar condiciones de búsqueda complejas.





  • Reducir la carga de la BD



  • Realizar el buffering de tablas sobre el servidor de aplicación.

  • Tipos de tablas más indicadas:

  • Tablas que se leen muy frecuentemente,

  • Tablas que cambian con muy poca frecuencia,

  • Tablas relativamente pequeñas (pocas líneas, pocas columnas, columnas cortas),

  • Tablas cuya actualización no es crítica en el tiempo. Por ejemplo tablas de parametrización y tablas de condiciones: AXXX, BXXX, CXXX, etc.

  • Evitar la lectura repetida de los datos.

  • Usar Bases de Datos Lógicas.



1.3 Recomendaciones Tips & Tricks por SAP





Estas recomendaciones incluyen ejemplos reales, cuyo tiempo de respuesta puede ser medido que pretenden ilustrar los aspectos comentados en el punto anterior.



Estas recomendaciones están localizables en el sistema mediante:



Herramientas  Workbench ABAP  Test  Análisis Tmpo. Ejecución  Tips & Tricks



Se pretende indicar que existen herramientas en el sistema que nos pueden ayudar en momentos de duda a elegir un algoritmo o conjunto de instrucciones más adecuado que otro. Se extrae una muestra a modo de ejemplo pero la lectura que debe realizarse de este apartado es que esta información debe ser consultada de forma online en caso de dudas o búsqueda de sugerencias en el momento de realizar la programación.





1.3.1 Instrucciones sobre la interfaz SAP-SQL





  • En una cláusula WHERE, el operador lógico NOT no está soportado por los índices. Por ejemplo:



WHERE fecha >= ‘19990212’ es mejor que

WHERE NOT FECHA <= ‘19990212’



  • Sentencias SELECT con CHECK. Especificar siempre que sea posible las condiciones de selección en la cláusula WHERE

  • Con la instrucción SELECT utilizar lista de campos en vez de SELECT * con el fin de disminuir el tráfico en la red.



  • Obtención de sumatorias, máximos, número de filas, ... Utilizar operadores MAX, COUNT, AVERAGE en la lista de campos en vez de realizarlos por programa. Disminuye el tráfico en la red.



  • Si se procesan los datos una sola vez, es preferible tratarlos en el bucle SELECT ... ENDSELECT que guardarlos en una tabla interna para posteriormente tratar la tabla interna mediante LOOP.




  • SELECT mediante vistas. Es conveniente sustituir los selects anidados por el uso de vistas.



SELECT * FROM DD01V

WHERE DOMNAME LIKE 'CHAR%'

AND DDLANGUAGE = SY-LANGU.

ENDSELECT.



es preferible a :



SELECT * FROM DD01L

WHERE DOMNAME LIKE 'CHAR%'

AND AS4LOCAL = 'A'.

SELECT SINGLE * FROM DD01T

WHERE DOMNAME = DD01L-DOMNAME

AND AS4LOCAL = 'A'

AND AS4VERS = DD01L-AS4VERS

AND DDLANGUAGE = SY-LANGU.



  • Tratamiento con arrays



    • Inserciones con array y actualizaciones de columnas



INSERT CUSTOMERS FROM TABLE itab.



es preferible a :



LOOP AT TAB.

INSERT INTO CUSTOMERS VALUES TAB.

ENDLOOP.



Utilizar actualizaciones de columna en vez de modificaciones de fila



UPDATE SFLIGHT SET SEATSOCC = SEATSOCC - 1.



es preferible a:



SELECT * FROM SFLIGHT.

SFLIGH T-SEATSOCC = SFLIGHT-SEACSOCC -1.

UPDATE SFLIGHT.

ENDSELECT.



    • Es preferible usar la sentencia SELECT con opción INTO que utilizar la sentencia APPEND dentro del bucle SELECT ... ENDSELECT





1.3.2 Tratamiento de cadenas de caracteres





  • Usar los operadores CO, CA, CS, etc, en lugar de programarlos. En strings largos, los tiempos de CPU aumentan considerablemente



  • No programar las sentencias para truncar strings o concatener, sino utilizar la instrucción SPLIT o CONCATENATE.





1.3.3 Tratamiento de tablas internas





  • Se recomienda el uso de la instrucción COLLECT a partir de la release 3.0 de SAP para construcción de tablas acumulativas.



  • Accesos por clave



READ TABLE TAB WITH KEY K = 'X' BINARY SEARCH es preferible a:



MOVE SPACE TO TAB.

TAB-K = 'X'.

READ TABLE TAB BINARY SEARCH.



  • Intentar siempre acceder a una tabla interna ya ordenada.



READ TABLE WITH KEY BINARY SEARCH. es preferible a:



READ TABLE WITH KEY.



  • En LOOP de tablas utilizar la cláusula WHERE



LOOP AT TAB WHERE K = KVAL.

.....

ENDLOOP es preferible a:



LOOP AT TAB.

CHECK TAB-K = KVAL.

.....

ENDLOOP.



  • Construcción de tablas ordenadas



    • No utilizar la instrucción APPEND itab SORTED BY



    • Utilizar el procedimiento de: 1º Llenar la tabla, 2º Ordenar la tabla

REFRESH TAB_DEST.

LOOP AT TAB_SRC.

APPEND TAB_SRC TO TAB_DEST.

ENDLOOP.

SORT TAB_DEST BY K



es preferible a:



REFRESH TAB_DEST.

LOOP AT TAB_SRC.

READ TABLE TAB_DEST WTTH KEY K= ....

INSERT TAB_SRC INTO TAB_DEST INDEX SY-INDEX.

ENDLOOP.



  • Construcción de tabla sin duplicados



    • Es preferible borrar las entradas duplicadas una vez construida la tabla utilizando el procedimiento de 1º - Llenar la tabla, 2º Ordenar la tabla, 3º Borrar duplicados



REFRESH TAB_DEST.

LOOP AT TAB_SRC

APPEND TAB_SRC TO TAB_DEST.

ENDLOOP

SORT TAB_DEST BY K.

DELETE ADJACENT DUPLICATES FROM TAB_DEST.



es preferible a:



REFRESH TAB_DEST.

LOOP AT TAB_SRC.

READ TABLE TAB_DEST WITH KEY K= TAB_SRC-K.

IF SY-SUBRC <> 0 .

INSERT TAB_SRC INTO TAB_DEST INDEX SY-INDEX.

ENDIF.

ENDLOOP.



  • Uso de áreas de trabajo evitando instrucciones MOVE



  • Copia de tablas internas: utilizar asignación directa de variables.



TAB_DEST[ ] = TAB_SRC[ ] es preferible a :



REFRESH TAB_DEST.

LOOP AT TAB_SRC INTO TAB_DEST.

APPEND TAB_DEST.

ENDLOOP.



  • Comparación de tablas internas: Dos tablas internas son iguales cuando tienen el mismo número de líneas y coinciden una a una.



IF TAB1[ ] = TAB2 [ ]

....

ENDIF.



Es preferible a realizar una barrido secuencial de una tabla e ir comparando con la entrada equivalente en la otra tabla.



  • Para ordenar tablas internas, especificar los campos sobre los que debe verificarse la ordenación.



SORT ITAB BY FIELD1 FIELD2. es preferible a:



SORT ITAB.





  • Para averiguar el número de registros en una tabla interna, utilizar la instrucción



DESCRIBE TABLE ITAB LINES C_LINEAS. es preferible a:



LOOP AT ITAB.

C_LINEAS = C_LINEAS + 1.

ENDLOOP.



  • JOIN de tablas, bucles anidados



    • Evitar recorridos secuenciales y plantearse accesos por índice en la segunda tabla o tabla más interna del bucle.


Suponiendo: tablas ordenadas, TAB2 contiene sólo entradas que existen en TAB1.



I2 = 1.

LOOP AT TAB1.

LOOP AT TAB2 FROM I2.

IF TAB2-K <> TAB1-K.

I2 = SY-TABIX.

EXIT.

ENDIF.

" ...

ENDLOOP.

ENDLOOP.



es preferible a :



LOOP AT TAB1.

LOOP AT TAB2 WHERE K = TAB1-K.

...

ENDLOOP.

ENDLOOP.



  • Inserción en una tabla desde otra



APPEND LINES OF TAB_SRC TO TAB_DEST. es preferible a:



LOOP AT TAB_SRC.

APPEND TAB_SRC TO TAB_DEST.

ENDLOOP.



  • Borrado de líneas.



Uso de índices para

DELETE TAB_DEST FROM 450 TO 550. es preferible a:



DO 101 TIMES.

DELETE TAB_DEST INDEX 450.

ENDDO.



DELETE TAB_DEST WHERE K = KVAL. Es preferible a:



LOOP AT TAB_DEST WHERE K = KVAL

DELETE TAB_DEST

ENDLOOP





1.3.4 Tratamiento de parámetros en rutinas y field-symbols





  • Especificar el tipo de parámetros en las rutinas:

    • Si se especifica el tipo de los parámetros formales de las rutinas en el código fuente del programa, el compilador de ABAP/4 puede optimizar mejor el fuente. Además, el riesgo de utilizar secuencias erróneas de parámetros disminuye.



  • Definir tipo en los field-symbols



    • Si se especifica el tipo del field-symbol, el compilador puede mejorar el rendimiento del programa.

FIELD-SYMBOLS: TYPE I. Es preferible a:



FIELD-SYMBOLS: .




1.3.5 Manejo de variables y tipos





  • Utilizar variables de tipo I para campos índices de bucle, no de tipo P.



  • Si los contenidos de las variables van a ser numéricas, definirlas tipo I.



  • En las asignaciones utilizar constantes con tipo mejor que literales.



CONSTANTS:

PI TYPE F VALUE '3.1415926535897932'.

DATA:

FLOAT TYPE F.

FLOAT = PI.



es preferible a:



DATA:

FLOAT TYPE F.

FLOAT = '3.1415926535897932'.



  • En cálculos aritméticos utilizar variables de tipo P.



DATA:

P1 TYPE P VALUE '123456789012345',

P2 TYPE P VALUE '543210987654321',

P1 = P1 + P2.



es preferible a:



DATA:

N1(15) TYPE N VALUE '123456789012345',

N2(15) TYPE N VALUE '543210987654321',

N1 = N1 + N2.



  • En cálculos aritméticos no mezclar variables de varios tipos a no ser absolutamente necesario, de esta forma evitaremos innecesarias conversiones de tipos.





1.4 Exposición de Sentencias SQL “caras”





1.4.1 Definición





Se definen de esta manera aquellas sentencias que:



  • Desde el punto de vista del usuario “el reloj de arena aparece en pantalla y permanece ahí un largo tiempo”



  • Desde el punto de vista del sistema: este tiene que leer muchos bloques de datos bien del buffer (supone una carga para el procesador), o bien del disco duro (lo que supone una sobrecarga para el sistema Input/Output).





1.4.2 Tipos





Para todas las BD y para todas las aplicaciones SAP y no-SAP, las sentencias SQL costosas pueden agotar los recursos del sistema operativo y causar graves problemas de rendimiento del sistema entero.



Existen, básicamente, dos tipos de sentencias SQL llamadas “caras” teniendo en cuenta el consumo de los recursos del sistema:



  • SENTENCIAS SQL CARAS DE TIPO 1:



  • Se procesan un gran número de registros pero el rendimiento es bueno.

  • Método de acceso adecuado

  • Por ejemplo: SQL Trace: > 10 Fetches por instrucción.



  • SENTENCIAS SQL CARAS DE TIPO 2:



  • Se procesa un número pequeño de registros pero hay un gran número de lecturas por registro o un elevado tiempo de respuesta por registro.

  • La estrategia de búsqueda no es eficiente, el método de acceso no es adecuado.

  • Por ejemplo:

    • Area de SQL compartida: > 100 peticiones de buffer por registro

    • SQL Trace: duración de cada Fetch > 500 ms.



Los datos que se necesitan para analizar sentencias SQL son:



  • Programas (para saber donde cambiar el código).

  • Sentencia SQL costosa.

  • Tabla implicada.

  • Indice utilizado.





1.4.3 Detección





Los tiempos de espera largos son el resultado del tiempo que emplea la BD en devolver los datos pedidos por R/3 y el que emplea R/3 en devolver la siguiente pantalla al usuario.



¿Cómo detectar las sentencias costosas?



  • Para encontrar el nombre del report o transacción que usa la sentencia SQL se puede utilizar:



  • Transacción SM50: Visualización de procesos de trabajo. (A partir de la ver. 4.6B también con la transacción ST04).

  • Transacción ST03: Reporting de Transacciones, carga de trabajo del sistema. (Ver más adelante el punto 6.2.4 Workload Monitor).



  • Para encontrar los nombres de las tablas accedidas y la sentencia SQL:



  • Transacción ST05: “Sql Trace”.

  • Transacción ST04: Area SQL compartida, Análisis de rendimiento de la BD.

  • Transacción SM50: Visualización de procesos de trabajo, anotamos el PID del proceso correspondiente y a continuación vamos a la transacción ST04:Monitor de procesos de la BD.



  • Para encontrar los índices implicados, usar la opción EXPLAIN en:



  • SQL Trace.

  • Area SQL compartida.

  • Monitor de proceso de la BD.



(Ver Anexo 4 “¿De Dónde procede la sentencia SQ?”).





1.4.4 Clasificación





Analizando los dos tipos de sentencias a través de SQL Trace (transacción ST05) apreciamos:



  • Para el primer tipo el tiempo medio de duración es de < 5 ms por registro o < 100 ms por FETCH. Los datos se transfieren con un rendimiento óptimo.

  • Para el segundo tipo la duración de un FETCH es > de 500 ms.



Si consultamos el Area SQL compartida (transacción ST04; Menú de análisis detallado; Peticiones SQL) para los dos tipos de sentencias anteriores, encontramos:



  • Para el tipo 1: < 50 peticiones al buffer por registro. Esta es una relación óptima entre el número de registros procesados y el número de bloques de datos escaneados.

  • Para el tipo 2: > 50. Esta no es una relación óptima y es consecuencia de una estrategia de búsqueda deficiente.





1.4.5 Soluciones





  • Programas estándar de SAP:



  • Solución : Consultar notas del OSS.



  • SENTENCIAS DEL TIPO 1:



  • Problema : Demasiados registros a transferir.

  • Solución : Re-escribir el código ABAP. (Ver apartado 1.4.2 “Normas Generales”).





  • SENTENCIAS DEL TIPO 2:



  • Problema 1 : No existen los índices adecuados.

  • Solución : Cambiar el código: añadir campos conocidos, etc.

Cambiar algún índice existente, en vez de crear uno nuevo.

Crear un índice nuevo (analizar antes el histograma de distribución de

los datos con la transacción DB05).

Quitar un índice (especialmente en versiones 3.x de Oracle con

optimizadores en modo normas).



O



  • Problema 2 : El Optimizador de la BD NO usa el acceso correcto.

  • Solución : Chequear la tabla de estadísticas; si la cláusula

WHERE es demasiado compleja, re-escribir el código.









Comentarios
Buscar
¡Sólo los usuarios registrados pueden escribir comentarios!

3.26 Copyright (C) 2008 Compojoom.com / Copyright (C) 2007 Alain Georgette / Copyright (C) 2006 Frantisek Hliva. All rights reserved."

 
home search