Somando Tabela Ped Item Muito Lento

Discussão em 'Progress 4GL' iniciado por alexandretm, Fevereiro 1, 2013.

  1. alexandretm

    alexandretm Membro Participativo

    Ola Amigos .
    Estou com problema programa Especifico, preciso fazer soma campos tabela ped-item, porem esta muito lentro para trazer o resultado.
    Se alguém puder me dar alguma dica de como posso melhorar a performance deste programa ?

    Segue código Fonte do calculo.:
    ASSIGN i-int[4] = 0 i-int[5] = 0 i-int[6] = 0.
    FOR EACH ped-venda NO-LOCK USE-INDEX ch-implant
    WHERE ped-venda.dt-implant >= DATE("01/" + STRING(MONTH(i-data),"99") + "/" + STRING(esparam-vendas.ano))
    AND ped-venda.dt-implant <= ( IF INT(MONTH(i-data)) = 12 THEN ( DATE("01/01/" + STRING(esparam-vendas.ano + 1 )) - 1 ) ELSE ( DATE("01/" + STRING(INT(MONTH(i-data) + 1),"99") + "/" + STRING(esparam-vendas.ano)) - 1 ) )
    AND ped-venda.dt-cancela = ?
    AND ped-venda.nome-abrev <> "LIMER-CART" ,
    EACH natur-oper OF ped-venda NO-LOCK
    WHERE natur-oper.emite-duplic = YES :

    FOR EACH ped-item OF ped-venda NO-LOCK
    WHERE ped-item.vl-preuni > 0 ,
    EACH ITEM OF ped-item NO-LOCK
    WHERE ITEM.fm-codigo <> "070" :
    ASSIGN i-int[4] = i-int[4] + ped-item.qt-pedida . /* Mes */
    IF ped-venda.dt-implant = i-data THEN DO:
    ASSIGN i-int[5] = i-int[5] + ped-item.qt-pedida . /* Dia */
    END.
    END.

    END.
    ASSIGN cMensal:SC
  2. TrombiniSP

    TrombiniSP Membro Participativo

    Olá,

    Primeiro de tudo retire todas essas funções da cláusula WHERE. Se vc tem que tratar estas variáveis de data faça antes de execura o "FOR EACH". Trate as datas e jogue os valores em variáveis.

    Código:
    dt-imp-ini = DATE("01/" + STRING(MONTH(i-data),"99") + "/" + STRING(esparam-vendas.ano)).
    
    dt-imp-fim =  ( IF INT(MONTH(i-data)) = 12 THEN ( DATE("01/01/" + STRING(esparam-vendas.ano + 1 )) - 1 ) ELSE ( DATE("01/" + STRING(INT(MONTH(i-data) + 1),"99") + "/" + STRING(esparam-vendas.ano)) - 1 ) ).
    
    Com estas variáveis vc vai tratar o campo dt-implant.

    Outra coisa é vc não fazer acesso a dados quando vc não necessita deles. Por exemplo, vc acessa a natur-oper mas não precisa dos registros que está colocando na memória (o buffer). Vc só precisa verificar o registro e tratar um campo.

    Ao invés de usar:

    Código:
    EACH natur-oper OF ped-venda NO-LOCK
    WHERE natur-oper.emite-duplic = YES
    Vc deve usar:

    Código:
    AND (CAN-FIND(EACH natur-oper OF ped-venda NO-LOCK
                 WHERE natur-oper.emite-duplic = YES))
    
    O mesmo exemplo acima se aplica a tabela ITEM. Siga o mesmo modo de tratamento. Vc não precisa do registro então não o deve colocar na memória. Usando o CAN-FIND vc verifica o registro sem acesso na memória o que vai deixar seu programa mais rápido.

    Expero que isso já ajude.

    Trombini
  3. alexandretm

    alexandretm Membro Participativo

    Trombini fiz teste, poderia verificar pra mim, pois, ganho foi de apenas 2 segundos, estava levando 8 segundos para fazer for each , agora 6 segundos, sera que eu fiz certo, segue novo código.Agora completo.
    DEF VAR i-int AS INTEGER EXTENT 12 INITIAL 0.
    DEF VAR i-data AS DATE INITIAL 01/31/2013.
    DEF VAR i-dt-ini AS DATE INITIAL ?.
    DEF VAR i-dt-fim AS DATE INITIAL ?.
    DEFINE VAR i-hora AS CHAR EXTENT 12 INITIAL "".
    ASSIGN i-hora[3] = STRING(TIME,"hh:mm:ss").
    FIND FIRST esparam-vendas
    WHERE esparam-vendas.cod-estabel = "1"
    AND esparam-vendas.ano = INT(YEAR(i-data))
    AND esparam-vendas.cancelado = NO NO-LOCK NO-ERROR.
    IF AVAIL esparam-vendas THEN DO:
    ASSIGN i-int[1] = 1 i-int[2] = 0 i-int[3] = 0.
    REPEAT:
    IF i-int[1] = 13 THEN LEAVE.
    ASSIGN i-int[2] = i-int[2] + esparam-vendas.quantidade[i-int[1]].
    ASSIGN i-int[1] = i-int[1] + 1.
    END.
    ASSIGN i-int[3] = ( IF INT(MONTH(i-data)) = 12 THEN INT( DATE("01/01/" + STRING(esparam-vendas.ano + 1 )) - DATE("01/" + STRING(MONTH(i-data),"99") + "/" + STRING(esparam-vendas.ano)))
    ELSE INT( DATE("01/" + STRING(INT(MONTH(i-data) + 1),"99") + "/" + STRING(esparam-vendas.ano)) - DATE("01/" + STRING(MONTH(i-data),"99") + "/" + STRING(esparam-vendas.ano))) ).
    ASSIGN i-hora[4] = STRING(TIME,"hh:mm:ss") .
    FOR EACH ems2ft.calen-prod NO-LOCK
    WHERE ems2ft.calen-prod.cod-estabel = "1"
    AND ems2ft.calen-prod.data >= DATE("01/" + STRING(MONTH(i-data),"99" ) + "/" + STRING(esparam-vendas.ano) )
    AND ems2ft.calen-prod.data <= ( IF INT(MONTH(i-data)) = 12 THEN DATE( DATE("01/01/" + STRING(esparam-vendas.ano + 1 ) ) - 1 )
    ELSE DATE( DATE("01/" + STRING( INT( MONTH(i-data) + 1 ),"99") + "/" + STRING(esparam-vendas.ano) ) - 1 ) )
    AND ems2ft.calen-prod.tipo-dia <> 1 :

    ASSIGN i-int[3] = i-int[3] - 1.

    END.
    ASSIGN i-hora[5] = STRING(TIME,"hh:mm:ss").
    ASSIGN i-int[4] = 0 i-int[5] = 0 i-int[6] = 0
    i-dt-ini = DATE("01/" + STRING(MONTH(i-data),"99") + "/" + STRING(esparam-vendas.ano))
    i-dt-fim = ( IF INT(MONTH(i-data)) = 12 THEN ( DATE("01/01/" + STRING(esparam-vendas.ano + 1 )) - 1 ) ELSE ( DATE("01/" + STRING(INT(MONTH(i-data) + 1),"99") + "/" + STRING(esparam-vendas.ano)) - 1 ) )
    i-hora[1] = STRING(TIME,"hh:mm:ss")
    .
    FOR EACH ped-venda NO-LOCK USE-INDEX ch-implant
    WHERE ped-venda.dt-implant >= i-dt-ini
    AND ped-venda.dt-implant <= i-dt-fim
    AND ped-venda.dt-cancela = ?
    AND ped-venda.nome-abrev <> "LIMER-CART" :

    IF CAN-FIND(FIRST natur-oper OF ped-venda NO-LOCK WHERE natur-oper.emite-duplic = YES ) THEN DO:

    FOR EACH ped-item OF ped-venda NO-LOCK
    WHERE ped-item.vl-preuni > 0 :

    IF CAN-FIND(FIRST ITEM OF ped-item NO-LOCK WHERE ITEM.fm-codigo <> "070" ) THEN DO:

    ASSIGN i-int[4] = i-int[4] + ped-item.qt-pedida . /* Mes */

    IF ped-venda.dt-implant = i-data THEN DO:
    ASSIGN i-int[5] = i-int[5] + ped-item.qt-pedida . /* Dia */
    END.
    END.
    END.
    END.

    END.
    ASSIGN i-hora[2] = STRING(TIME,"hh:mm:ss").
    DISP i-int[3] ' Qt Dias' SKIP
    i-int[4] ' Mes' SKIP
    i-int[5] ' Dia' SKIP
    i-hora[1] 'Inicial ' SKIP
    i-hora[2] 'Final' SKIP
    i-hora[3] 'Inicio Programa' SKIP
    i-hora[4] 'Apos Repeat' SKIP
    i-hora[5] 'Apos \Calendario' .
    END.
  4. alexandretm

    alexandretm Membro Participativo

    Código:
    DEF VAR i-int AS INTEGER EXTENT 12 INITIAL 0.
    DEF VAR i-data AS DATE INITIAL 01/31/2013.
    DEF VAR i-dt-ini AS DATE INITIAL ?.
    DEF VAR i-dt-fim AS DATE INITIAL ?.
    DEFINE VAR i-hora AS CHAR EXTENT 12 INITIAL "".
    ASSIGN i-hora[3] = STRING(TIME,"hh:mm:ss").
    FIND FIRST esparam-vendas 
         WHERE esparam-vendas.cod-estabel = "1"
          AND  esparam-vendas.ano        = INT(YEAR(i-data))
          AND  esparam-vendas.cancelado  = NO NO-LOCK NO-ERROR.
    IF AVAIL esparam-vendas THEN DO:
        ASSIGN i-int[1] = 1 i-int[2] = 0 i-int[3] = 0.
        REPEAT:
            IF i-int[1] = 13 THEN LEAVE.
            ASSIGN i-int[2] = i-int[2] + esparam-vendas.quantidade[i-int[1]].
            ASSIGN i-int[1] = i-int[1] + 1.
        END.
        ASSIGN i-int[3] = ( IF INT(MONTH(i-data)) = 12 THEN INT( DATE("01/01/" + STRING(esparam-vendas.ano + 1 )) - DATE("01/" + STRING(MONTH(i-data),"99") + "/" + STRING(esparam-vendas.ano)))
                                                       ELSE INT( DATE("01/" + STRING(INT(MONTH(i-data) + 1),"99") + "/" + STRING(esparam-vendas.ano)) - DATE("01/" + STRING(MONTH(i-data),"99") + "/" + STRING(esparam-vendas.ano))) ).
        ASSIGN i-hora[4] = STRING(TIME,"hh:mm:ss") .
        FOR EACH ems2ft.calen-prod NO-LOCK
            WHERE ems2ft.calen-prod.cod-estabel = "1"
             AND  ems2ft.calen-prod.data        >= DATE("01/" + STRING(MONTH(i-data),"99" ) + "/" + STRING(esparam-vendas.ano) ) 
             AND  ems2ft.calen-prod.data        <=  ( IF INT(MONTH(i-data)) = 12 THEN DATE( DATE("01/01/" + STRING(esparam-vendas.ano + 1 ) ) - 1 )
                                                                         ELSE DATE( DATE("01/" + STRING( INT( MONTH(i-data) + 1 ),"99") + "/" + STRING(esparam-vendas.ano) ) - 1 ) )
             AND  ems2ft.calen-prod.tipo-dia    <> 1 :
    
            ASSIGN i-int[3] = i-int[3] - 1.
    
        END.
        ASSIGN i-hora[5] = STRING(TIME,"hh:mm:ss").
        ASSIGN i-int[4] = 0 i-int[5] = 0 i-int[6] = 0
               i-dt-ini = DATE("01/" + STRING(MONTH(i-data),"99") + "/" + STRING(esparam-vendas.ano)) 
               i-dt-fim = ( IF INT(MONTH(i-data)) = 12 THEN ( DATE("01/01/" + STRING(esparam-vendas.ano + 1 )) - 1 ) ELSE ( DATE("01/" + STRING(INT(MONTH(i-data) + 1),"99") + "/" + STRING(esparam-vendas.ano)) - 1 ) )
               i-hora[1] = STRING(TIME,"hh:mm:ss")
            .
        FOR EACH  ped-venda NO-LOCK USE-INDEX ch-implant
            WHERE ped-venda.dt-implant >= i-dt-ini
              AND ped-venda.dt-implant <= i-dt-fim
              AND ped-venda.dt-cancela = ?
              AND ped-venda.nome-abrev <> "LIMER-CART" :
            
            IF CAN-FIND(FIRST natur-oper OF ped-venda NO-LOCK WHERE natur-oper.emite-duplic = YES )  THEN DO:
    
                FOR EACH ped-item OF ped-venda NO-LOCK
                   WHERE ped-item.vl-preuni > 0 :
    
                   IF CAN-FIND(FIRST ITEM OF ped-item NO-LOCK WHERE ITEM.fm-codigo <> "070" ) THEN DO:
                    
                        ASSIGN i-int[4] = i-int[4] + ped-item.qt-pedida . /* Mes */
                            
                        IF ped-venda.dt-implant = i-data THEN DO:
                            ASSIGN i-int[5] = i-int[5] + ped-item.qt-pedida . /* Dia */
                        END.
                   END.
                END.
            END.
    
        END.
        ASSIGN i-hora[2] = STRING(TIME,"hh:mm:ss").
        DISP i-int[3] ' Qt Dias' SKIP
             i-int[4] ' Mes'     SKIP
             i-int[5] ' Dia'     SKIP
             i-hora[1] 'Inicial ' SKIP
             i-hora[2] 'Final'    SKIP
             i-hora[3] 'Inicio Programa' SKIP 
            i-hora[4] 'Apos Repeat'  SKIP
            i-hora[5] 'Apos \Calendario'  .
    END.
    
    
  5. TrombiniSP

    TrombiniSP Membro Participativo

    Olá,

    Quando eu sugeri utlizar o CAN-FIND foi para o fazer dentro da clásula WHERE. Ficaria como abaixo. E já que vc vai mexer neste código verifique se não há outros indices que lhe ajudem. Se não houver não há muito o que fazer. Creio que ficará um pouco mais rápido assim.

    Código:
    FOR EACH ped-venda NO-LOCK USE-INDEX ch-implant
       WHERE ped-venda.dt-implant >= i-dt-ini
         AND ped-venda.dt-implant <= i-dt-fim
         AND ped-venda.dt-cancela = ?
         AND ped-venda.nome-abrev <> "LIMER-CART"
         AND CAN-FIND(FIRST natur-oper OF ped-venda NO-LOCK
    				WHERE natur-oper.emite-duplic = YES ),
        EACH ped-item OF ped-venda NO-LOCK
       WHERE ped-item.vl-preuni > 0
         AND CAN-FIND(FIRST ITEM OF ped-item NO-LOCK WHERE ITEM.fm-codigo <> "070" ):
    
    
        ASSIGN i-int[4] = i-int[4] + ped-item.qt-pedida . /* Mes */
    
        IF ped-venda.dt-implant = i-data THEN
            ASSIGN i-int[5] = i-int[5] + ped-item.qt-pedida . /* Dia */
    
    END.
    
  6. alexandretm

    alexandretm Membro Participativo

    Valeu Trombini, muito obrigado pela ajuda, reduziu de 8 para 2 segundos a aplicação.

Compartilhe esta Página