Melhorar performance For Each

Discussão em 'Progress 4GL' iniciado por diegocf, Setembro 24, 2010.

  1. diegocf

    diegocf Membro Participativo

    Boa tarde pessoal,

    To com uma duvida basica acho que pra maioria de voces, é o seguinte estou tentando buscar algumas informações atraves de um FOR EACH, mas quando estou relacionando as 2 tabelas em questão demora anos-luz para executar, sera que voces tem uma dica de como poderia ficar o codigo ?

    --------------------------------------------------------------------------------------------------------------
    DEF VAR h-prog AS HANDLE NO-UNDO.
    RUN utp/ut-utils.p PERSISTENT SET h-prog.


    OUTPUT TO "C:\TEMP\EXPORTA_NOTAS.CSV".


    PUT UNFORMATTED "COD-REP" ";"
    "REPRESENTANTE" ";"
    "COD-ESTAB" ";"
    "COD-CLIENTE" ";"
    "CLIENTE" ";"
    "DT EMISSAO" ";"
    "NR-NOTA-FISCAL" ";"
    "VL NOTA-FISCAL" ";"
    "COMISSAO" ";"
    "VL COMISSAO" ";"
    "COMISSAO" ";"

    SKIP(01).


    FOR EACH nota-fiscal use-index ch-nome-repres WHERE nota-fiscal.cod-emitente = 18431 AND
    nota-fiscal.dt-cancela = ? NO-LOCK,
    each fat-repre where nota-fiscal.no-ab-reppri = fat-repre.nome-ab-rep.


    PUT UNFORMATTED nota-fiscal.cod-rep ";"
    nota-fiscal.no-ab-reppri ";"
    nota-fiscal.cod-estabel ";"
    nota-fiscal.cod-emitente ";"
    nota-fiscal.nome-ab-cli ";"
    nota-fiscal.dt-emis-nota ";"
    nota-fiscal.nr-nota-fis ";"
    nota-fiscal.vl-tot-nota ";"
    fat-repre.perc-comis ";"
    fat-repre.vl-base-calc-comis ";"




    SKIP.


    END.



    /*PUT
    "" SKIP
    "------------------------------------------------------------------------" SKIP(01).*/



    /*******************************************************************************************************************/
    RUN EXECUTE IN h-prog(INPUT "excel.exe", INPUT "c:\temp\EXPORTA_NOTAS.csv").
    OUTPUT CLOSE.
  2. eduardo.leite

    eduardo.leite Equipe de Suporte Moderador Equipe de Suporte

    Bom, caro colega, é o seguinte:

    01) Vocês está lendo os registros da tabela nota fiscal que atendam a situação de COD-EMITENTE = {VALOR} e que não esteja CANCELADA e depois lê todos os faturamentos do representante desta nota fiscal emitente.

    02) Até aqui tudo ok, é isso mesmo, o que está impactando na leitura é o USE-INDEX, pois o indice que você escolheu CH-NOME-REPRES consta dos seguintes campos NOME-AB-REPPRI + ESTABELECIMENTO + SERIE + NOTA FISCAL, sendo assim o Progress irá ler toda a sua base de dados para selecionar somente aqueles que sejam do EMITENTE e que não esteja CANCELADO.

    Sendo assim, toda vez que usar USE-INDEX somente aconselha-se quando o WHERE tiver os campos da chave, não tendo deixe sem o USE-INDEX ou use algum que tenha os campos do where (exemplo "ch-emi-nota" que consta do COD-EMITENTE + EMISSAO DA NOTA + SITUAÇAO).

    No seu exemplo elimine o USE-INDEX e você vai ver que será processado muito mais rápido.

    Já o segundo FOR EACH "each fat-repre where nota-fiscal.no-ab-reppri = fat-repre.nome-ab-rep" está incompleto, pois você está mandando efetuar a leitura de todas as notas fiscais de um representante de uma nota, ou seja, imagine:

    01) Você tem 05 Notas Fiscais (001,002,003,004,005) para o Emitente 18431 que nestas notas o representante seja "FULANO";
    02) Na sua leitura o resultado seria:
    NF 001 - 18431 - NFREP 001 - FULANO
    NF 001 - 18431 - NFREP 002 - FULANO
    NF 001 - 18431 - NFREP 003 - FULANO
    NF 001 - 18431 - NFREP 004 - FULANO
    NF 001 - 18431 - NFREP 005 - FULANO
    NF 002 - 18431 - NFREP 001 - FULANO
    NF 002 - 18431 - NFREP 002 - FULANO
    NF 002 - 18431 - NFREP 003 - FULANO
    NF 002 - 18431 - NFREP 004 - FULANO
    NF 002 - 18431 - NFREP 005 - FULANO
    NF 003 - 18431 - NFREP 001 - FULANO
    NF 003 - 18431 - NFREP 002 - FULANO
    NF 003 - 18431 - NFREP 003 - FULANO
    NF 003 - 18431 - NFREP 004 - FULANO
    NF 003 - 18431 - NFREP 005 - FULANO

    Percebe que para cada nota fiscal foi repetido todas as notas fiscais de representante, isto porque no segundo for each você não linkou o ft-repres com a nota-fiscal pela indice principal (Estabelecimento + Série + Nr Fatura) sendo assim, o seu for each deverá ficar da seguinte maneira:

    Código:
    for each nota-fiscal 
       where nota-fiscal.cod-emitente = 18431 
         and nota-fiscal.dt-cancela   = ? no-lock,
        each fat-repre use-index ch-fatrep
       where fat-repre.cod-estabel = nota-fiscal.cod-estabel
             fat-repre.serie       = nota-fiscal.serie      
             fat-repre.nr-fatura   = nota-fiscal.nr-fatura
       where fat-repre.nome-ab-rep = nota-fiscal.no-ab-reppri:
    
        put unformatted 
            nota-fiscal.cod-rep          ";"
            nota-fiscal.no-ab-reppri     ";" 
            nota-fiscal.cod-estabel      ";" 
            nota-fiscal.cod-emitente     ";" 
            nota-fiscal.nome-ab-cli      ";"
            nota-fiscal.dt-emis-nota     ";"
            nota-fiscal.nr-nota-fis      ";"
            nota-fiscal.vl-tot-nota      ";"
            fat-repre.perc-comis         ";"
            fat-repre.vl-base-calc-comis ";"
            skip.
    
    end.
    
  3. startbit

    startbit Membro Participativo

    o segundo each está certo?

    Você está querendo encontrar na tabela fat-repre onde nota-fiscal.no-ab-reppri = fat-repre.nome-ab-rep;

    Não seria " each fat-repre where fat-repre.nome-ab-rep = nota-fiscal.no-ab-reppri"?

    Sua consulta está gerando resultados?

    E a demora pode ser justificada pela consulta encadeada...

    *Para cada nota-fiscal onde o emitente é 18431, cada fat-repre onde nome-ab-rep = nota-fiscal.no-ab-reppri*

    Resumindo, cada each na primeira, busca n resultados na segunda.

Compartilhe esta Página