Turbinar Consulta

Discussão em 'Progress 4GL' iniciado por kikofr, Novembro 30, 2009.

  1. kikofr

    kikofr Membro Participativo

    Boa tarde.

    Estou desenvolvendo um relatório utilizando a lógica abaixo. Acontece que os usuários estão reclamando da performance do relatório e estou quebrando a cabeça para tentar melhorar a performance do relatório.

    Alguem teria uma dica para me dar para conseguir melhorar a perfomance dessa consulta?

    Código:
    DEFINE VARIABLE i-devolucao AS INTEGER     NO-UNDO.
    DEFINE VARIABLE vDataInicial            AS DATE        NO-UNDO.
    DEFINE VARIABLE vEstabelecimentoInicial AS INTEGER     NO-UNDO.
    DEFINE VARIABLE vContagem               AS INTEGER     NO-UNDO.
    ASSIGN vDataInicial            = pDataInicial
           vEstabelecimentoInicial = pEstabInicial.
    REPEAT WHILE vDataInicial <= pDataFinal.
            FOR EACH mgmov.nota-fiscal NO-LOCK /*USE-INDEX nfftrm-20*/
               WHERE mgmov.nota-fiscal.dt-emis-nota  = vDataInicial
                 AND mgmov.nota-fiscal.dt-cancela   = ?
                 AND mgmov.nota-fiscal.cod-estabel  >= string(pEstabInicial)
                 AND mgmov.nota-fiscal.cod-estabel  <= string(pEstabFinal)
                 AND mgmov.nota-fiscal.cod-rep      >= pRepresentanteInicial 
                 AND mgmov.nota-fiscal.cod-rep      <= pRepresentanteFinal
                 AND mgmov.nota-fiscal.cod-emitente >= pCodClienteInicial
                 AND mgmov.nota-fiscal.cod-emitente <= pCodClienteFinal
                 AND mgmov.nota-fiscal.nr-embarque  >= pEmbarqueInicial
                 AND mgmov.nota-fiscal.nr-embarque  <= pEmbarqueFinal
                 
                BREAK BY nota-fiscal.nr-nota-fis.
                run pi-acompanhar  in h-acomp (INPUT  STRING(vDataInicial) + " - " + nota-fiscal.nr-nota-fis).                
                FIND FIRST mgcad.emitente NO-LOCK WHERE mgcad.emitente.cod-emitente = mgmov.nota-fiscal.cod-emitente NO-ERROR.
                
                IF AVAIL mgcad.emitente THEN DO:
                    IF mgcad.emitente.cod-gr-cli <= pGrupoClienteInicial AND mgcad.emitente.cod-gr-cli >= pGrupoClienteFinal THEN
                        NEXT.
                    IF mgcad.emitente.cod-canal-venda <= pCanalVendaInicial AND mgcad.emitente.cod-canal-venda >= pCanalVendaFinal THEN
                        NEXT.
                    IF mgcad.emitente.nome-matriz <= STRING(pMatrizInicial) AND mgcad.emitente.nome-matriz >= STRING(pMatrizInicial)  THEN
                        NEXT.
                    IF mgcad.emitente.categoria <= String(pCategoriaInicial) AND mgcad.emitente.categoria >= STRING(pCategoriaFinal) THEN 
                        NEXT.
                    FIND FIRST fruki-ext-emitente OF emitente NO-LOCK NO-ERROR.
                    IF AVAIL fruki-ext-emitente THEN DO:
                        IF p-l-foco AND NOT fruki-ext-emitente.log-foco THEN DO:                    
                            NEXT.
                        END.
                        ELSE
                            IF NOT p-l-foco AND fruki-ext-emitente.log-foco THEN DO:                        
                                NEXT.
                            END.
                         IF p-i-codigo-cadeia-inicial > fruki-ext-emitente.codigo-cadeia OR p-i-codigo-cadeia-final < fruki-ext-emitente.codigo-cadeia THEN
                             NEXT.               
                    END.
                        
                END.            
                
                FIND FIRST hierarquia NO-LOCK WHERE hierarquia.representante = mgmov.nota-fiscal.cod-rep 
                                         AND hierarquia.gerencia     >= pGerenciaInicial
                                         AND hierarquia.gerencia     <= pGerenciaFinal
                                         AND hierarquia.CV           >= pCVInicial
                                         AND hierarquia.CV           <= pCVFinal
                                         AND hierarquia.coordenador  >= pCoordenadorInicial
                                         AND hierarquia.coordenador  <= pCoordenadorFinal NO-ERROR.
                /*Descarta linha que não esta na hierarquia indicada*/
                IF NOT AVAIL hierarquia THEN DO:
                    NEXT.
                END.
                
                FIND FIRST mgcad.natur-oper NO-LOCK WHERE mgcad.natur-oper.nat-operacao = mgmov.nota-fiscal.nat-oper NO-ERROR.
                IF mgcad.natur-oper.nat-operacao = "190902" THEN 
                    NEXT.
                IF AVAIL mgcad.natur-oper THEN DO:
                    FIND FIRST mgesp.ext-natur-oper NO-LOCK WHERE mgesp.ext-natur-oper.nat-operacao = mgcad.natur-oper.nat-operacao NO-ERROR.
        
                    IF pVenda = NO THEN DO:
                        IF (mgesp.ext-natur-oper.log-bonificacao = NO AND 
                            mgesp.ext-natur-oper.log-comodato = NO AND
                            mgesp.ext-natur-oper.log-troca = NO) THEN
                            NEXT.
                    END.
        
                    IF NOT AVAIL mgesp.ext-natur-oper THEN 
                        NEXT.
        
                    IF AVAIL mgesp.ext-natur-oper THEN DO:
                        IF (mgesp.ext-natur-oper.log-bonificacao = YES OR 
                            mgesp.ext-natur-oper.log-comodato = YES OR
                            mgesp.ext-natur-oper.log-troca = YES) THEN DO:
                            IF pBonificacao = NO THEN 
                            IF mgesp.ext-natur-oper.log-bonificacao <> pBonificacao 
                                AND mgesp.ext-natur-oper.log-comodato = NO
                                AND mgesp.ext-natur-oper.log-troca = NO THEN
                                NEXT.
                            IF mgesp.ext-natur-oper.log-comodato <> pComodato
                                AND mgesp.ext-natur-oper.log-troca = NO
                                AND mgesp.ext-natur-oper.log-bonificacao = NO THEN
                                NEXT.
                            IF mgesp.ext-natur-oper.log-troca <> pTroca 
                                AND mgesp.ext-natur-oper.log-comodato = NO
                                AND mgesp.ext-natur-oper.log-bonificacao = NO THEN
                                NEXT.
                        END.
                    END.
                END.
                FOR EACH it-nota-fisc OF nota-fiscal NO-LOCK:            
                    FIND FIRST tt-dados 
                        WHERE tt-dados.codigo-cliente = mgmov.nota-fiscal.cod-emitente 
                          AND tt-dados.codigo-item = mgmov.it-nota-fisc.it-codigo NO-ERROR.
                    IF NOT AVAIL tt-dados THEN DO:
                        CREATE tt-dados.
                        ASSIGN tt-dados.gerente        = hierarquia.gerencia
                               tt-dados.cv             = hierarquia.cv
                               tt-dados.coordenador    = hierarquia.coordenador
                               tt-dados.representante  = hierarquia.representante
                               tt-dados.codigo-cliente = mgmov.nota-fiscal.cod-emitente
                               tt-dados.nome-cliente   = mgcad.emitente.nome-emit
                               tt-dados.codigo-item    = mgmov.it-nota-fisc.it-codigo.                           
                    END.                            
                END.
        END.
     
        ASSIGN vDataInicial = vDataInicial + 1
               vEstabelecimentoInicial = pEstabInicial.
    
    END.
  2. fdantas

    fdantas Administrator Moderador

    Comece utilizando a clausula Fields nos for eachs...
  3. kikofr

    kikofr Membro Participativo

    Valeu Dantas, vou testar usar a clausula Fields,

    mas, pela sua experiencia, o ganho de performance utilizando a clausula fields é consideravel?
  4. fdantas

    fdantas Administrator Moderador

    Opa com certeza ainda mais em tabelas da datasul que tem um zilhao de campos char.

    Imagine o seguinte for each

    Código:
    FOR EACH emitente NO-LOCK.
        DISP emitente.cod-emit.
    END.
    
    Imagine que ele vai trazer do banco o registro todo, e no for each abaixo ele traria somente o codigo do emitente, imagine que na tabela emitente cada registro tem com certeza mais de 1000 caracteres... e o codigo do emitente uns 10 chutando alto.
    Isso causa um impacto grande... mas só é perceptivel em rotinas grandes ou em um conjunto de rotinas... pois temos que lembrar que isso vai melhorar a performance do servidor... melhorando os outros usuários... ou seja coisas dificeis de se calcular.

    Código:
    FOR EACH emitente FIELDS(cod-emit) NO-LOCK.
        DISP emitente.cod-emit.
    END.
    
    

Compartilhe esta Página