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.
Valeu Dantas, vou testar usar a clausula Fields, mas, pela sua experiencia, o ganho de performance utilizando a clausula fields é consideravel?
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.