Como optimizo una consulta con "SELECT SINGLE"

Colapsar
X
 
  • Tiempo
  • Mostrar
Limpiar Todo
nuevos mensajes
  • sealons
    Junior Member
    • feb
    • 19

    #16
    aupa gente,
    La ST05 que tengo en este sistema me aparece en aleman, y no me acuerdo de los nombres en castellano, pero mas o menos a ver si nos entendemos . Lo he usado poco, pero se trata de marcar el acceso SQL-Trace en las opciones de la izquierda, viene por defecto. En las de la derecha activar el trace. En otro modo que ya tienes que tener abierto, realizas la ejecucion del programa que quieres analizar. Despues detienes el analisis en las opciones de la derecha, y finalmente examinas los resultados con otra de las opciones.
    A mi me pone 'Trace einschalten' en la primera, activar trace; 'Trace ausschalten' en la tercera, interrumpir trace; y 'Trace anzeigen' en la cuarta, mostrar trace; seguro que a ti te viene en castellano.
    Al mostrar el trace te aparece la ventanita con tu usuario...y al aceptar ves los accesos y tiempos de la ejecucion que hayas realizado, o de lo que sea que estes realizando en ese momento, para no liarse es mejor tener solo lo que interesa...
    no se si te habre ayudado con tanto aleman , espero que si

    saludos,
    sealons.

    Comentario

    • dmgman
      Senior Member
      • feb
      • 149

      #17
      Hola a todos,
      Al fin he conseguido usar un indice, pero dado que los existentes no tenian la composicion de campos y/o orden que necesitaba, he creado uno propio.
      El proceso solo gracias a este indice ha bajado 30 segundos.
      Aunque la verdad que creo que no hace mucha gracia que cada uno que necesite un acceso por determinados campos, coja y se cree uno. Vamos que ya me han dicho, que es una buena manera, pero que ya hay mucho indices...

      Para los que como yo nos sabiamos de indices, os digo que el orden de campos del indice y de los parametros del select dentro de la sentencia where debe de ser la misma.

      Espero q con esto valga, pq trabajar con tablas de BD tan grandes es una odisea hacer que sea eficiente.

      Por cierto, he descubierto 2 transacciones q me han comentado q me serian de ayuda, los que se encuentran en las transacciones, ST04 y SM50. Si alguien los conoce, y me pudiera contar como interpretarlas y manejarlas, se lo agradeceria.
      Editado por última vez por dmgman; 26/09/2006, 07:59:36.
      Carpe Diem !!

      Comentario

      • ballan
        Senior Member
        • oct
        • 671

        #18
        Los indices solo funcionan si se utiliza el operador de igualdad y el orden de las clausulas depende, generalmente es muy optimo poner los campos en el select y en el where en el mismo orden que estan en la tabla pero si hay una clausula que sabemos que es muy restrictiva deberia ir primero en la where, por otro lado la eleccion del indice por parte del motor del sgbd es algo bastante complicado pero hay una manera de "forzar" al select para que vaya por un determinado indice, aqui os dejo un ejemplo

        SELECT k~vbeln k~augru k~zsfecins k~zsordser
        p~posnr p~matnr p~pstyv p~uepos p~kwmeng
        f~vbtyp_n f~rfmng f~erdat f~bwart
        INTO TABLE i_informe
        FROM vbak AS k
        INNER JOIN vbap AS p ON k~vbeln = p~vbeln
        LEFT OUTER JOIN vbfa AS f ON p~vbeln = f~vbelv
        AND p~posnr = f~posnv
        WHERE k~auart IN rg_auart
        AND k~zsordser IN s_ordser
        %_HINTS
        ORACLE 'INDEX ("VBAK" "VBAK~Z01")'.

        aqui forzaria al select a ir por el indice Z01 de la tabla vbak

        otra forma que el estandar utiliza bastante para optimizar los select es partir los rangos en fragmentos mas pequeños y unir los resultados con select appending

        Un saludo

        Comentario

        • worwa
          Junior Member
          • jun
          • 4

          #19
          LA transaccion ST05 se utiliza basicamente por los BASIS para medir las cuotas de las trazas SQL para utilizarla es preferible ingresar al sistema en el idioma ingles (ya que ingrasamos en español, el idioma en el cual se va a cargar es ALEMAN, -no me pregunten por que-) y alli seleccionamos el tipo de traza que queremos evaluar (si es SQL Trace, Enqueue Trace, RFC Trace o Buffer Trace) y se selecciona la opcion de la traza con los parametros que ella pida, entre las que se encuentran:

          Activate Trace: Sirve para activar el medidor de la traza para todos los selects de los programas que este corriendo el usuario en curso.

          Activate Trace with Filter: Sirve para activar el medidor de la traza para los selects de un programas que este corriendo el usuario en curso, en ese momento, podemos especificar la transacción, el nombre del programa, el usuario, la identificacion del proceso e include y podemos incluir o excluir de acuerdo a lo que necesitemos evaluar.

          Deactivate Trace: Desactiva la traza SQL para que despues podamos ver el resultado de la Evaluacion el Display Trace.

          Display Trace: Aqui se puede ver el resultado de el desempeño de la traza que decidimos evaluar, podemos especificar una serie de opciones que se nos presentan o simplemente activar con las que ya vienen por defecto.

          Enter SQL Statment: Esta opcion evalua una Traza SQL que nosotros introduzcamos en el editor que se nos presenta en la pantalla, recomiendo no usar variables sino valores directamente.

          En lo personal solo he utilizado en lo que se refire a los tipos de traza las SQL Trace (que miden las trazas SQL en tiempo de ejecución de un programa, para lo que hago un debugin del programa que contiene la traza a evaluar en un nodo y corro la trancación en otro) y las RFC Trace (que miden - a mi parecer - la conectividad entre las BAPIS y los web dinpro).

          Espero haberles ayudado en algo.

          P.D.: Todo lo anteriormente dicho lo he sacado de mi propia autoria y experiencia, cualquier cosa pueden contactarme a mi correo worwaenrique@yahoo.com.

          P.D2.: Voy a ver si puedo Hacer una presentacion de anteriormente narrado y les escribo de nuevo.
          Editado por última vez por worwa; 14/12/2006, 14:06:35.

          Comentario

          • Mauricio Hidalgo
            Senior Member
            • may
            • 481

            #20
            Aprovecho de comentar que en algunas querys es visto que le agregan unos HINTS para mejorar la performance.

            Por ejemplo originalmente había esta query.

            SELECT lednr bzobj kalnr kalka kadky tvers bwvar
            kkzma posnr matnr werks typps lstar menge
            meeht wrtfw_pos fwaer tpreis peinh pmeht wertn
            INTO TABLE t_ckis
            FROM ckis
            FOR ALL ENTRIES IN t_keko
            WHERE lednr = '00'
            AND bzobj = t_keko-bzobj
            AND kalnr = t_keko-kalnr
            AND kalka = t_keko-kalka
            AND kadky = t_keko-kadky
            AND tvers = t_keko-tvers
            AND bwvar = t_keko-bwvar
            AND kkzma = t_keko-kkzma.

            lentisima en PRD, la dejaron así

            SELECT lednr bzobj kalnr kalka kadky tvers bwvar
            kkzma posnr matnr werks typps lstar menge
            meeht wrtfw_pos fwaer tpreis peinh pmeht wertn
            INTO TABLE t_ckis
            FROM ckis
            FOR ALL ENTRIES IN t_keko
            WHERE lednr = '00'
            AND bzobj = t_keko-bzobj
            AND kalnr = t_keko-kalnr
            AND kalka = t_keko-kalka
            AND kadky = t_keko-kadky
            AND tvers = t_keko-tvers
            AND bwvar = t_keko-bwvar
            AND kkzma = t_keko-kkzma
            %_HINTS DB6 'CONVERT_FAE_TO_CTE'
            DB6 'USE_OPTLEVEL 0'.

            y la performance de la query mejoró notablemente. Por decir algo
            si antes se demorar 17000 mil segundos, habrá quedado en 500 segundos.

            como?, ni idea!!, por que no he podido encontrar información acerca de esos HINTS.

            dejó la inquietud, haber si alguien pillo en BD nos puede aclarar esto.

            saludos a Todos.

            Comentario

            • sap2006
              Senior Member
              • mar
              • 134

              #21
              Hace tiempo lei un manual de optimizacion sql para SAP muy bueno, lo buscaré y lo postearé. A modo de resumen (muchas cosas ya comentadas anteriormente) los pilares se basan en:

              *Entrar por el indice. El orden de como esté definido el indice SI
              importa.

              *Utilizar condiciones positivas.situar la condición que más frecuentemente sea falsa en primer lugar.

              *Evitar bucles SELECT anidados. Utilizar la clausula FOR ALL ENTRIES, joins, vistas...

              *Evitar condiciones de búsqueda complejas.

              *En selects single (solo lectura, en tablas pequeñas y sin muchos movimientos) utilizar la clausula "BYPASSING BUFFER".

              En la se30, si vais a TIPS&TRIKS podeis ver ejemplos de rendimiento y evaluar vuestro codigo.

              Salu2.


              AQUI LO TENEIS: SACADO DEL FORO SAP4.COM.

              1.1 Objetivo









              El objetivo que se persigue con estas recomendaciones es orientar y concienciar a los desarrolladores de que ABAP presenta un conjunto de instrucciones reducido, pero con muchas opciones o posibilidades de realizar una misma consulta o instrucción.






              Es evidente que las mejoras en unos pocos milisegundos no son importantes aisladamente, pero en muchos casos podremos aplicar estas mejoras en bucles o rutinas que se ejecuten cientos de veces, lo que hará que estos milisegundos ahorrados se multipliquen.






              Por regla general el rendimiento de los programas ABAP viene determinado en gran parte por la “eficiencia” de sus accesos a las Bases de Datos (BD).






              Para entender cómo las sentencias SQL afectan a la ejecución de programas ABAP, es necesario entender la arquitectura del sistema que hay por debajo. Los procesos de trabajo de un servidor de aplicación están “conectados” al servidor de la BD como usuarios (clientes) durante el tiempo que el sistema R/3 está activo. El gestor de la BD (Data Dase Management System - DBMS) realiza la conexión entre usuarios y datos.






              Cada sistema de BD utiliza un optimizador cuya tarea es crear el plan de ejecución para las sentencias SQL (por ejemplo determinar entre el uso de un índice en vez de leer en la BD). Hay dos tipos de optimizadores:






              Optimizadores basados en la norma: analizan la estructura de una sentencia SQL (las partes SELECT y WHERE sin sus valores) y los índices. Después usa un algoritmo para calcular qué método usar para ejecutar la sentencia.


              Optimizadores basados en el coste: usan el procedimiento anterior pero también utilizan tablas de estadísticas. Las tablas de estadísticas contienen los valores más bajos y altos de los campos, o un histograma con la distribución de los datos en la tabla. Este tipo de optimizadores mejoran el tiempo de acceso a las BD, pero tienen la desventaja de que las tablas de estadísticas necesitan actualizarse periódicamente.






              (Consultar Anexo 3: “Notas sobre las Tablas de Estadísticas”)






              Nota: SAP bajo Oracle permite el uso del optimizador basado en coste a partir de la release 4.x. Anteriormente eran basados en la norma.





              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&#243;n en la cl&#225;usula WHERE


              Con la instrucci&#243;n SELECT utilizar lista de campos en vez de SELECT * con el fin de disminuir el tr&#225;fico en la red.






              Obtenci&#243;n de sumatorias, m&#225;ximos, n&#250;mero de filas, ... Utilizar operadores MAX, COUNT, AVERAGE en la lista de campos en vez de realizarlos por programa. Disminuye el tr&#225;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&#243;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&#243;n SPLIT o CONCATENATE.









              1.3.3 Tratamiento de tablas internas








              Se recomienda el uso de la instrucci&#243;n COLLECT a partir de la release 3.0 de SAP para construcci&#243;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&#225;usula WHERE






              LOOP AT TAB WHERE K = KVAL.


              .....


              ENDLOOP es preferible a:






              LOOP AT TAB.


              CHECK TAB-K = KVAL.


              .....


              ENDLOOP.






              Construcci&#243;n de tablas ordenadas






              No utilizar la instrucci&#243;n APPEND itab SORTED BY






              Utilizar el procedimiento de: 1&#186; Llenar la tabla, 2&#186; 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&#243;n de tabla sin duplicados






              Es preferible borrar las entradas duplicadas una vez construida la tabla utilizando el procedimiento de 1&#186; - Llenar la tabla, 2&#186; Ordenar la tabla, 3&#186; 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 &#225;reas de trabajo evitando instrucciones MOVE






              Copia de tablas internas: utilizar asignaci&#243;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&#243;n de tablas internas: Dos tablas internas son iguales cuando tienen el mismo n&#250;mero de l&#237;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&#243;n.






              SORT ITAB BY FIELD1 FIELD2. es preferible a:






              SORT ITAB.










              Para averiguar el n&#250;mero de registros en una tabla interna, utilizar la instrucci&#243;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 &#237;ndice en la segunda tabla o tabla m&#225;s interna del bucle.




              Suponiendo: tablas ordenadas, TAB2 contiene s&#243;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&#243;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&#237;neas.






              Uso de &#237;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&#225;metros en rutinas y field-symbols








              Especificar el tipo de par&#225;metros en las rutinas:


              Si se especifica el tipo de los par&#225;metros formales de las rutinas en el c&#243;digo fuente del programa, el compilador de ABAP/4 puede optimizar mejor el fuente. Adem&#225;s, el riesgo de utilizar secuencias err&#243;neas de par&#225;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 &#237;ndices de bucle, no de tipo P.






              Si los contenidos de las variables van a ser num&#233;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&#225;lculos aritm&#233;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&#225;lculos aritm&#233;ticos no mezclar variables de varios tipos a no ser absolutamente necesario, de esta forma evitaremos innecesarias conversiones de tipos.









              1.4 Exposici&#243;n de Sentencias SQL “caras”







              1.4.1 Definici&#243;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&#237; 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&#225;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&#250;mero de registros pero el rendimiento es bueno.


              M&#233;todo de acceso adecuado


              Por ejemplo: SQL Trace: > 10 Fetches por instrucci&#243;n.






              SENTENCIAS SQL CARAS DE TIPO 2:






              Se procesa un n&#250;mero peque&#241;o de registros pero hay un gran n&#250;mero de lecturas por registro o un elevado tiempo de respuesta por registro.


              La estrategia de b&#250;squeda no es eficiente, el m&#233;todo de acceso no es adecuado.


              Por ejemplo:


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


              SQL Trace: duraci&#243;n de cada Fetch > 500 ms.






              Los datos que se necesitan para analizar sentencias SQL son:






              Programas (para saber donde cambiar el c&#243;digo).


              Sentencia SQL costosa.


              Tabla implicada.


              Indice utilizado.









              1.4.3 Detecci&#243;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.






              &#191;C&#243;mo detectar las sentencias costosas?






              Para encontrar el nombre del report o transacci&#243;n que usa la sentencia SQL se puede utilizar:






              Transacci&#243;n SM50: Visualizaci&#243;n de procesos de trabajo. (A partir de la ver. 4.6B tambi&#233;n con la transacci&#243;n ST04).


              Transacci&#243;n ST03: Reporting de Transacciones, carga de trabajo del sistema. (Ver m&#225;s adelante el punto 6.2.4 Workload Monitor).






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






              Transacci&#243;n ST05: “Sql Trace”.


              Transacci&#243;n ST04: Area SQL compartida, An&#225;lisis de rendimiento de la BD.


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






              Para encontrar los &#237;ndices implicados, usar la opci&#243;n EXPLAIN en:






              SQL Trace.


              Area SQL compartida.


              Monitor de proceso de la BD.






              (Ver Anexo 4 “&#191;De D&#243;nde procede la sentencia SQ?”).









              1.4.4 Clasificaci&#243;n








              Analizando los dos tipos de sentencias a trav&#233;s de SQL Trace (transacci&#243;n ST05) apreciamos:






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


              Para el segundo tipo la duraci&#243;n de un FETCH es > de 500 ms.






              Si consultamos el Area SQL compartida (transacci&#243;n ST04; Men&#250; de an&#225;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&#243;n &#243;ptima entre el n&#250;mero de registros procesados y el n&#250;mero de bloques de datos escaneados.


              Para el tipo 2: > 50. Esta no es una relaci&#243;n &#243;ptima y es consecuencia de una estrategia de b&#250;squeda deficiente.









              1.4.5 Soluciones








              Programas est&#225;ndar de SAP:






              Soluci&#243;n : Consultar notas del OSS.






              SENTENCIAS DEL TIPO 1:






              Problema : Demasiados registros a transferir.


              Soluci&#243;n : Re-escribir el c&#243;digo ABAP. (Ver apartado 1.4.2 “Normas Generales”).










              SENTENCIAS DEL TIPO 2:






              Problema 1 : No existen los &#237;ndices adecuados.


              Soluci&#243;n : Cambiar el c&#243;digo: a&#241;adir campos conocidos, etc.


              Cambiar alg&#250;n &#237;ndice existente, en vez de crear uno nuevo.


              Crear un &#237;ndice nuevo (analizar antes el histograma de distribuci&#243;n de


              los datos con la transacci&#243;n DB05).


              Quitar un &#237;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&#243;n : Chequear la tabla de estad&#237;sticas; si la cl&#225;usula


              WHERE es demasiado compleja, re-escribir el c&#243;digo.
              Editado por última vez por sap2006; 15/12/2006, 07:57:42.

              Comentario

              • dmgman
                Senior Member
                • feb
                • 149

                #22
                Creo que es mas facil y mejor postear directamente la web:
                http://sap4.com/contentid-176.html
                Carpe Diem !!

                Comentario

                • guts11
                  Junior Member
                  • may
                  • 1

                  #23
                  El Select Single esta dentro de un loop??
                  De ser asi estaria mejor volcar todo a una tabla interna, de los campos que necesites.
                  Saludos

                  Originalmente publicado por dmgman
                  Hola a todos,
                  Me han encargado optimizar un report ya que el tiempo de ejecucion es demasiado elevado.
                  Tras analizarlo encuentro que casi la mitad de la ejecucion se va en un "SELECT SINGLE" a la tabla BSAS que contiene 5 millones de registros.
                  Esta es la famosa sentencia:

                  Código:
                      SELECT SINGLE bukrs belnr gjahr
                        INTO (bsas-bukrs, bsas-belnr, bsas-gjahr)
                          FROM bsas
                          WHERE bukrs EQ bkpf-bukrs
                            AND augdt IN r_budat
                            AND augbl EQ bkpf-belnr
                            AND blart NE 'ZI'.
                  No llevo mucho tiempo en Sap y no se me ocurre q alternativa podria tomar.
                  Gracias

                  Comentario

                  • tomasm
                    Member
                    • jun
                    • 87

                    #24
                    Una alternativa, que funciona relativamente bien en consonancia con el esfuerzo realizado para conseguirla.

                    Usar las transacciones SQ01 y SQ02 (Generador de querys de SAP)

                    Crear la query deseada y fisgar en el código generado.

                    Que trabaje SAP !!!!

                    Saludos !!!

                    Comentario

                    • Atlas
                      Senior Member
                      • ago
                      • 107

                      #25
                      Pues me dijeron una cosa que tal vez podria haber ayudado en su momento.

                      Se supone (llevo un dia que ya no se que pensar) que para tostar menos la base de datos es mejor en vez de un select single dentro de un loop, un select into for all entries de la tabla del loop y dentro del loop un read a la tabla que llenamos con el for all entreis...

                      Comentario

                      • sconoredhot
                        Senior Member
                        • feb
                        • 341

                        #26
                        Tengo el presentimiento de que ese select esta adentro de un loop... no podrias mandar todo el código completo?
                        Sebas

                        Desarrollador ABAP.

                        Comentario

                        • DCErick
                          Moderator
                          • mar
                          • 1090

                          #27
                          Orden de Campos en Indice

                          Hola.. ya lei el post y no vi si que comentaran si el campo mandt es obligatorio ponerlo en el select para que tome en cuenta el indice.

                          Tengo un indice para una tabla z con la siguiente estructura

                          MANDT
                          KUNNR
                          GJAHR
                          ZPERI
                          Y mi select es el siguiente


                          SELECT * FROM zdp_movtos INTO TABLE ti_zdp_movtos
                          WHERE kunnr = s_zdp_movtos-kunnr
                          AND gjahr = s_zdp_movtos-gjahr
                          AND zperi = s_zdp_movtos-zperi.
                          Como pueden notar yo no estoy poniendo el mandante en la clausala where.

                          Mi otra duda es si al usar un indice el proceso cuando lo ves desde la sm50 en el campo Acción tiene que cambiar a lectura directa? o seguira quedando como lectura secuencial?
                          -------------------
                          ¿Dudas para descargar manuales? Ver este tema -> Cómo descargar manuales de la sección "Descargas" ?

                          Comentario

                          • moji87
                            Junior Member
                            • may
                            • 19

                            #28
                            Yo quiero hacer un select single pero no me sale,tengo este error:
                            THIS LIST "(ZCLIENTES-NOMBRE,ZCLIENTES-APELLIDOS)"
                            AFTER "INTO" IS NOT OF THE FORM ABAP [...]OR CONTAINS AN UNDEFINITED FIELD.

                            y el código es:
                            REPORT ZCONSULTA.

                            select single NOMBRE APELLIDOS
                            INTO (ZCLIENTES-NOMBRE,ZCLIENTES-APELLIDOS)
                            FROM ZCLIENTES
                            WHERE IDCLIENTE EQ 1.

                            Igual me falta hacer la vista pero es muy lioso y nose seguir.
                            Ayudadme ,por favor.

                            Comentario

                            • vanesamacri
                              Senior Member
                              • jun
                              • 146

                              #29
                              Originalmente publicado por moji87
                              Yo quiero hacer un select single pero no me sale,tengo este error:
                              THIS LIST "(ZCLIENTES-NOMBRE,ZCLIENTES-APELLIDOS)"
                              AFTER "INTO" IS NOT OF THE FORM ABAP [...]OR CONTAINS AN UNDEFINITED FIELD.

                              y el código es:
                              REPORT ZCONSULTA.

                              select single NOMBRE APELLIDOS
                              INTO (ZCLIENTES-NOMBRE,ZCLIENTES-APELLIDOS)
                              FROM ZCLIENTES
                              WHERE IDCLIENTE EQ 1.

                              Igual me falta hacer la vista pero es muy lioso y nose seguir.
                              Ayudadme ,por favor.
                              Buenas tardes.

                              El problema radica en que no definiste en memoria el destino de los campos. Podrías hacer esto declarando en el código lo siguiente:

                              TABLES ZCLIENTES.
                              En este caso, los datos recuperados se almacenarán en la cabecera generada para la tabla de diccionario.

                              Como alternativa, también podés declarar un registro (o variables individuales) de tipo que coincida con los datos a recuperar en la consulta.

                              Saludos.

                              Comentario

                              • moji87
                                Junior Member
                                • may
                                • 19

                                #30
                                Gracias...

                                Buenos días,
                                Entonces...¿Cómo quedaría el código completo?
                                Gracias y saludos.

                                Saludos.

                                Comentario

                                Trabajando...