#1
|
|||
|
|||
Mejora al performance codigo
Hola, ¿Cómo mejorar rendimiento a estos 2 selects?
LOOP AT lt_lfa1 INTO wa_lfa1. *lt_lfa1 tiene 6 mil registros se deben revisar si tienen registros en las dos tablas siguiente (EBAN y EKKO) SELECT banfn FROM eban INTO lv_banfn WHERE lifnr = wa_lfa1-lifnr AND badat IN lt_badat. ENDSELECT. IF sy-subrc NE 0. SELECT ebeln FROM ekko INTO lv_ebeln WHERE lifnr = wa_lfa1-lifnr AND bedat IN lt_badat. ENDSELECT. IF sy-subrc NE 0. Actualmente se está tardando unos 50 min en procesar ¿Hay forma de mejorarlo? |
#2
|
|||
|
|||
Hola.
En primer lugar, voy a asumir que la tabla interna lt_lfa1 es del tipo de la tabla transparente LFA1 y que es desde allí de donde obtiene sus valores, por lo que no tendrá valores repetidos en el campo LIFNR (ya que el mismo conforma la totalidad de la clave de dicha tabla). En caso negativo y que sí tenga valores repetidos, manejarse con tabla auxiliar en el que se supriman los registros que posean valores repetidos del campo LIFNR para preservar solamente una entrada por cada valor único. El principal problema que veo en la lógica actual que atenta en contra del rendimiento son los SELECT...ENDSELECTs adentro del LOOP, lo cuales, de acuerdo a las buenas prácticas de programación, deberían evitarse a toda costa siempre que sea posible. Sacar a los SELECT de adentro del LOOP y re-escribirlos de la siguiente manera: SELECT banfn FROM eban INTO TABLE lt_banfn " Tabla interna con un único campo del tipo del campo BANFN de la tabla EBAN FOR ALL ENTRIES IN lt_lfa1 WHERE lifnr EQ lt_lfa1-lifnr AND badat IN lt_badat. SELECT ebeln FROM ekko INTO TABLE lt_ebeln " Tabla interna con un único campo del tipo del campo EBELN de la tabla EKKO FOR ALL ENTRIES IN lt_lfa1 WHERE lifnr EQ lt_lfa1-lifnr AND bedat IN lt_badat. De esta manera, se van a realizar solamente dos accesos a la base de datos, uno por cada SELECT, en los cuales se va a extraer la totalidad de los registros relevantes en solamente dos accesos a la BD. Actualmente en tu código se están realizando al menos dos accesos a la base de datos por cada iteración del LOOP. Si la tabla que está siendo recorrida tiene 6000 registros, estamos hablando de al menos 12000 accesos individuales a la base de datos. Una vez realizadas ambas extracciones, ahí sí podés recorrer la tabla LT_LFA1 y mediante READ TABLEs, verificar la presencia en las otras dos tablas internas resultado de las consultas (estas iteraciones ya no van a incurrir en accesos a base de datos puesto que la información ya se encuentra extraída). Ya con este cambio deberías notar una mejora en los tiempos de ejecución para ese apartado de la lógica. Por último, un comentario a tener en cuenta: se recomienda (también, una cuestión de buenas prácticas) que antes de hacer un SELECT...FOR ALL ENTRIES, verificar que la tabla interna del FOR ALL ENTRIES no se encuentre vacía, ya que de no tener ningún registro, se estaría consultando sin aplicar la condición que la utiliza y puede tener un impacto negativo en la performance (ya que se podría estar trayendo pila de información sin filtrar). Desconozco cuál será el requerimiento de tu desarrollo (quizás sea correcto traer la totalidad de los registros), nomás lo menciono como algo para que tengas en cuenta en el futuro. Cualquier cosa, avisá a ver cómo te fue. Un saludo. Iván |
#3
|
|||
|
|||
Ivan gracias por tu respuesta.
Aplique lo de eliminar los ENDSELECT dentro del LOOP, pero seguia bastante lento, el tema estaba en los índices de la tabla transparente. Los campos que estoy usando para buscar en la EBAN no existían como índice, lo cual hace mas lenta la búsqueda. Opte por crear un nuevo índice y cambiando el SELECT por SELECT SINGLE y funciono correctamente. Muchas gracias, y espero que el tema le sirva a cualquier otro miembro. ¡SALUDOS! |
Herramientas | Buscar en Tema |
Desplegado | |
|
|