Optimizar Codigo

Colapsar
X
 
  • Tiempo
  • Mostrar
Limpiar Todo
nuevos mensajes
  • acha3318
    Senior Member
    • abr
    • 182

    #1

    Optimizar Codigo

    Saludos a todos,

    No se como hacer, para optimizar este codigo el cual se demora demasiado tiempo al rededor de 19 minutos.

    Los siguientes son RANGES:
    r_matnr
    r_werks
    r_lgort
    r_bwart
    r_sobkz

    SELECT mblnr mjahr waers zeile bwart matnr werks lgort charg bwtar kzvbr
    kzbew sobkz kzzug bustm bustw mengu wertu shkzg menge meins dmbtr
    dmbum xauto kzbws insmk smbln sjahr smblp umwrk bstme
    INTO TABLE it_lmseg
    FROM mseg
    FOR ALL ENTRIES IN it_mkpf
    WHERE mblnr EQ it_mkpf-mblnr AND
    mjahr EQ it_mkpf-mjahr AND
    matnr IN r_matnr AND
    werks IN r_werks AND
    lgort IN r_lgort AND
    bwart IN r_bwart AND
    sobkz IN r_sobkz.

    Si alguien sabe como voltear este codigo para hacerlo mas eficiente recibo comentarios, por otro lado, yo cree indices, por los campos del where y de igual forma se demora.

    Gracias por la ayuda que me puedan dar.
  • gib8107
    Member
    • may
    • 44

    #2
    ..

    Yo he tenido muy mala experiencia con la sentencia for all entries, en lo personal lo cambio a que seleccione de 1000 en 1000 con muy bienos resultados


    yo tengo en mi sistema

    Sistema operativo Windows 20XX
    Tipo máquina 8x AMD64 L

    Sistema base datos MSSQL
    Release 9.00.2047
    Versión componentes SAP ECC 6.0

    SAP_ABA 700 0020 SAPKA70020 Componente multiaplicaciones
    SAP_BASIS 700 0020 SAPKB70020 Sistema Base SAP
    PI_BASIS 2005_1_700 0020 SAPKIPYJ7K PI_BASIS 2005_1_700

    pero esta mejora la empezamos a aplicar desde hace como dos años


    La idea es seleccionar de 1000 en 1000 los registros (SQL truena con mas de 1500 registros) y cada vez que cambie el año, que son los dos datos que son variables por lo que estas utilizando el for all entries

    tambien puedews copiar el programa y aplicarle un trace con la TC ST05 y ver si mejhora o empeora el rendimiento
    Código:
     
    data: 
    vl_MJAHR like it_mkpf-mjahr,
    vl_MJAHR_ant like it_mkpf-mjahr,
    .
    ranges r_mblnr for mkpf-mblnr .
    ** se ordena la tabla interna por el año + numero de documento.
    sort it_mkpf by mjahr,mblnr.
    loop at it_mkpf.
     if sy-tabix eq 1.
      vl_MJAHR = vl_MJAHR_ant = it_mkpf-mjahr.
     endif.
    ** antes de anexar el numero de documento se verifica que se a el mismo año 
     if vl_MJAHR eq vl_MJAHR_ant.
      r_mblnr-option = 'EQ'.
      r_mblnr-sing = 'I'.
      r_mblnr-low = it_mkpf-mblnr.
      collect r_mblnr.
     else.
      SELECT mblnr mjahr waers zeile bwart matnr werks lgort charg bwtar kzvbr
      kzbew sobkz kzzug bustm bustw mengu wertu shkzg menge meins dmbtr
      dmbum xauto kzbws insmk smbln sjahr smblp umwrk bstme
      INTO TABLE it_lmseg
      FROM mseg
    **  FOR ALL ENTRIES IN it_mkpf se ignora la linea
      WHERE 
    **  mblnr EQ it_mkpf-mblnr AND se ignora la linea
    **  mjahr EQ it_mkpf-mjahr AND se ignora la linea
      mblnr in r_mblnr   AND
      mjahr EQ vl_MJAHR  AND
      matnr IN r_matnr AND
      werks IN r_werks AND
      lgort IN r_lgort AND
      bwart IN r_bwart AND
      sobkz IN r_sobkz.
      clear r_mblnr   .
      refresh r_mblnr .
    ** se tiene que igualar el año 
    ** y se le da collect a el numero de documento  
      r_mblnr-option = 'EQ'.
      r_mblnr-sing = 'I'.
      r_mblnr-low = it_mkpf-mblnr.
      collect r_mblnr.
      vl_MJAHR = vl_MJAHR_ant = it_mkpf-mjahr.
    endif.
    describe r_mblnr.
     if sy-fill eq 1000.
      SELECT mblnr mjahr waers zeile bwart matnr werks lgort charg bwtar kzvbr
      kzbew sobkz kzzug bustm bustw mengu wertu shkzg menge meins dmbtr
      dmbum xauto kzbws insmk smbln sjahr smblp umwrk bstme
      INTO TABLE it_lmseg
      FROM mseg
    **  FOR ALL ENTRIES IN it_mkpf se ignora la linea
      WHERE 
    **  mblnr EQ it_mkpf-mblnr AND se ignora la linea
    **  mjahr EQ it_mkpf-mjahr AND se ignora la linea
      mblnr in r_mblnr   AND
      mjahr EQ vl_MJAHR  AND
      matnr IN r_matnr AND
      werks IN r_werks AND
      lgort IN r_lgort AND
      bwart IN r_bwart AND
      sobkz IN r_sobkz.
      clear r_mblnr   .
      refresh r_mblnr .
     endif.
     
    endloop.
    **se verifica si no se tienen mas datos  para extraeer 
     if sy-fill ne 0.
      SELECT mblnr mjahr waers zeile bwart matnr werks lgort charg bwtar kzvbr
      kzbew sobkz kzzug bustm bustw mengu wertu shkzg menge meins dmbtr
      dmbum xauto kzbws insmk smbln sjahr smblp umwrk bstme
      INTO TABLE it_lmseg
      FROM mseg
    **  FOR ALL ENTRIES IN it_mkpf se ignora la linea
      WHERE 
    **  mblnr EQ it_mkpf-mblnr AND se ignora la linea
    **  mjahr EQ it_mkpf-mjahr AND se ignora la linea
      mblnr in r_mblnr   AND
      mjahr EQ vl_MJAHR  AND
      matnr IN r_matnr AND
      werks IN r_werks AND
      lgort IN r_lgort AND
      bwart IN r_bwart AND
      sobkz IN r_sobkz.
      clear r_mblnr   .
      refresh r_mblnr .
     endif.

    Comentario

    • francesc
      Member
      • mar
      • 58

      #3
      Podrias probar a hacer la selección sólo con la condición de la clave, es decir el campo MBLNR y posteriormente con la tabla interna obtenida aplicar las otras condiciones. Una cosa, ten presente que si la tabla que le pasas al FOR ALL ENTRIES está vacía entonces el SELECT te seleccionará todo el contenido de la tabla de la BB.DD a la que accedes.

      Comentario

      • hugoa77
        Senior Member
        • may
        • 130

        #4
        Hola, coincido con francesc... o tambien te sugeriría que utilices un inner join. Este último suele ser más eficiente que el for all entries...
        Nos cuentas como te fue.
        Slds,

        Comentario

        • acha3318
          Senior Member
          • abr
          • 182

          #5
          Optimizar Codigo

          Gracias a todos por sus aportes, de todas maneras, la consulta si es pesadita.

          Por ahora me toca quedarme asi, hasta que me invente otra cosa.


          Gracias a todos.

          Comentario

          • hugoa77
            Senior Member
            • may
            • 130

            #6
            un aporte más... por ahí te aporta un poco de luz...

            Optimización en el acceso a la Base de Datos

            Unos simples consejos son los siguientes:

            Si se va a acceder a varias tablas relaciones, es recomendable crear una vista con las tablas relacionadas y accesar a ella.

            Con la opción FOR ALL ENTRIES se consigue que las entradas que se consiguieron en el primer select (tabla driver) se consigan en el segundo select por lo que se ejecutaría el segundo select solo una vez.

            SELECT matnr FROM mara INTO TABLE imara WHERE cond.
            SELECT * FROM mard FOR ALL ENTRIES IN imara WHERE mantr = imara-matnr.

            Con la Instrucción FORL ALL ENTRIES hay que tener sumo cuidado en la manera en que se va a usar, primero se debe asegurar que la tabla driver con la se va a comparar no se encuentre vacia, pues si es así, traería toda la data que esté en la base de datos, perjudicando el performance del programa, y segundo, si la tabla interna tiene muchos registros, el select a la Base de Datos sería mucha mas lento pues si utilizaría mucha memoria.

            Para hacer mas eficiente el FOR ALL ENTRIES es recomendable, borrar los valores duplicado de la tabla driver, ordenarla y si es posible convertirla en una tabla de rangos usando la sentencia BETWEEN.

            FOR ALL ENTRIES IN imara WHERE matnr >= imara-matnr
            AND matnr <= imara-matnr.

            Es recomendable y mas rápido indicarle al SELECT que campos va leer, si no se necesitan todos ellos.

            SELECT campo1 campo2 campo3 FROM TABLE tabla INTO TABLE itabla.

            Donde itabla debe estar declarada con los campos que se quieren seleccionar de la tabla.

            Fuente: http://abaperitos.blogspot.com/2010/...rformance.html
            Slds

            Comentario

            Trabajando...