Bom dia Galera, Ca estou eu novamente, amigo agora preciso de uma ajuda basica de voces, estou gerando um relatorio em csv com varias tabelas relacionadas, e ele esta muito lento, o maximo que eu consegui fazer foi com a configuração atual do programa, como posso melhorar eles alguem poderia alterar o codigo para uma logica mais rapida, pois um periodo de 5 dias demora mais de 10 minutos. Conto com o apoio de voces. Código: def var h-prog as handle no-undo. def var h-acomp as handle no-undo. def var tot-preco as decimal no-undo. def var vl-ipi as decimal no-undo. def var preco-total as decimal no-undo. run utp/ut-utils.p persistent set h-prog. run utp/ut-acomp.p persistent set h-acomp. {utp/ut-liter.i "Aguarde..."} run pi-inicializar in h-acomp (input "Selecionando Pedidos de Compra..."). output to "c:\temp\exporta_pedidos_compra.csv" no-convert page-size 0. /* IMPRIME CABEALHO DAS ORDENS DE COMPRA E PEDIDOS DE COMPRA */ put unformatted /* Coluna A */ "Estab" ";" /* Estabelcimento */ /* Coluna B */ "Ordem" ";" /* Ordem de Compra */ /* Coluna C */ "Item" ";" /* Item */ /* Coluna D */ "Desc" ";" /* Descriaä do item */ /* Coluna E */ "Fornec" ";" /* Fornecedor */ /* Coluna F */ "Dt Emiss" ";" /* Data de EmissÆo */ /* Coluna G */ "Dt Entr" ";" /* Data de Entrega */ /* Coluna H */ "Pr.Unit" ";" /* Preo Unitario */ /* Coluna I */ "Qtd" ";" /* Quantidade */ /* Coluna J */ "Pr.Merc" ";" /* Preo da Mercad. */ /* Coluna K */ "Vl IPI" ";" /* Valor IPI */ /* Coluna L */ "Pr.Total" ";" /* Preo Total */ /* Coluna M */ "Sit" ";" /* SituaÆo */ /* Coluna N */ "Ped" ";" /* Numero do Pedido */ /* Coluna O */ "Dt Ped" ";" /* Data do Pedido */ /* Coluna P */ "Req" ";" /* RequisiÆo */ /* Coluna Q */ "Dt Req" ";" /* Dt RequisiÆo */ /* Coluna C */ "Sit.Req" ";" /* SituaÆo Requis. */ /* Coluna D */ "Estado" ";" /* Estado Requis. */ /* Coluna E */ "Item Req" ";" /* Item Requis. */ /* Coluna F */ "Desc.Item" ";" /* Descr. Item Req. */ /* Coluna G */ "Qtd Req" ";" /* Qtd Requis. */ /* Coluna H */ "Valor" ";" /* Valor Requis. */ skip . /* FAZ A BUSCA NAS ORDENS DE COMPRA , PEDIDOS DE COMPRA E REQUISIOES */ assign tot-preco = 0. assign vl-ipi = 0. assign preco-total = 0. for each requisicao use-index requisicao where requisicao.dt-requisicao >= 10/01/2010 and requisicao.dt-requisicao <= 10/05/2010, each it-requisicao use-index item-req where requisicao.nr-requisicao = it-requisicao.nr-requisicao, each ordem-compra of requisicao use-index requis where ordem-compra.nr-requisicao = requisicao.nr-requisicao, each pedido-compr of ordem-compra use-index numero, each prazo-compra of ordem-compra use-index data, each item where item.it-codigo = ordem-compra.it-codigo, each emitente where emitente.cod-emitente = ordem-compra.cod-emitente break by ordem-compra.numero-ordem : IF LAST-OF(ordem-compra.numero-ordem) THEN do: assign tot-preco = ordem-compra.qt-solic * ordem-compra.preco-fornec . assign vl-ipi = tot-preco * ordem-compra.aliquota-ipi / 100 . assign preco-total = tot-preco + vl-ipi. run pi-acompanhar in h-acomp (input "Pedido Compra: " + string(pedido-compr.num-pedido)). /* IMPRIME OS REGISTROS DAS ORDENS DE COMPRA, PEDIDOS DE COMPRA e REQUISIåES */ put unformatted ordem-compra.cod-estabel ";" ordem-compra.numero-ordem ";" ordem-compra.it-codigo ";" item.desc-item ";" emitente.nome-abrev ";" ordem-compra.data-emissao ";" prazo-compra.data-entrega ";" ordem-compra.preco-fornec format ">>>,>>>,>>9.99" ";" ordem-compra.qt-solic ";" tot-preco format ">>>,>>>,>>9.99" ";" /* Preco da merc */ vl-ipi format ">>,>>9.99" ";" /* Valor do Ipi */ preco-total format ">>>,>>>,>>9.99" ";" /* Preco merc + Ipi */ entry(ordem-compra.situacao,"Nao Confirmada,Confirmado,Cotada,Eliminada,Em Cotacao,Recebido") ";" pedido-compr.num-pedido ";" pedido-compr.data-pedido ";" requisicao.nr-requisicao ";" requisicao.dt-requisicao ";" entry(requisicao.situacao,"Aberta,Fechada,Pendente Compl.,Com. Ordem") ";" entry(requisicao.estado,"Aprovado,Nao Aprovado") ";" it-requisicao.it-codigo ";" item.desc-item ";" it-requisicao.qt-requisitada ";" it-requisicao.val-item ";" skip. end. end. output close. run execute in h-prog(input "excel.exe", input "c:\temp\exporta_pedidos_compra.csv"). run pi-finalizar in h-acomp.
Caro colega, segue em anexo a rotina modificada para agilizar a leitura, considerações: 01) Sempre que efetuar somente leitura (não irá fazer update nas tabelas) e por segurança, coloque NO-LOCK em cada leitura de tabela; 02) Somente utilize o USE-INDEX quando realmente precisar informar ao progress que deverá usar a chave definida, caso contrário deixei que o próprio progress procure pela chave mais ideal, veja só: a) use-index requisicao: Você mandou o progres usar a chave "requisicao" e na seleção usou o campo dt-requisicao, a chave "requisicao" tem o número da requisição, sendo assim ele procurou em toda a base validando se a data da requisição obedece a seleção. Excute a rotina e nos fala quanto tempo passou a executar, ok?
Isso, USE-INDEX ou qualquer tipo de hint só deveria ser utilizado como última opção, quando você realmente testou e viu que esta é a alternativa. Outro problema do USE-INDEX é que se surgir um índice novo e você compilar teu código, ele nem será considerado. E pode ser o índice perfeito... Com USE-INDEX você está limitando as opções. Outras duas considerações são a ordem de acesso as tabelas e o algorítimo de JOIN empregado. Eu não conheço a cardinalidade nem a distribuição dos teus dados, mas é algo a ser considerado.
Minhas dicas são: 1) Compile seu programa com a opção XREF 2) Analise o arquivo e procure por WHOLE-INDEX a tabela que tiver isso é pq nao esta usando index nenhum e faz FULLSCAN 3) Faça uma revisão para reduzir o escopo de leitura quando possível 4) Coloque registros menores (tabelas pequenas) em temp-table e nao faça mais find ou for each na tabela e sim na TT 5) Substitua o comando FIND por CAN-FIND quando for apenas um teste logico sem precisar do registro 6) Substituia FIND FIRST por FOR FIRST quando for utilizar poucos campos da tabela 7) Use o comando FIELDS nos comandos FOR EACH e FOR FIRST 8) Faça o WHERE trabalhar de acordo com uma chave 9) Ue o USE-INDEX nos FOR EACHs que a chave não for 100% ideal 10) Lembre-se que no WHERE o PROGRESS interpreta 7 regras - Equality matchs - Range Matches, - Equality Range Matches, etc... 11) Uso de funções em FOR EACH ou FIND FIRST é mais lento que efetuar o teste antes e armazenar em uma variavel. Cara Performance é algo longo... Trabalhei 12 anos com Datasul sendo 6 dentrod a Datasul e 3 só com performance...passei pelo projeto da Grendene desde 1999 onde a performance foi um ponto crucial para virada do projeto... atualmente estão com o mesmo problema no FLEX...mas como agora ta cheio de camadas a culpa nao é só do progress... chega disso...estou aqui só pra ajudar um pouco o que aprendi neste caminho... visitem o blog do nosso produto http://4glnews.blogspot.com um abraço e boa sorte...