[RESOLVIDO] For eachs demorados

Discussão em 'EMS , HCM e Totvs 11' iniciado por bootstrapmaster, Outubro 29, 2015.

Status do Tópico:
Não esta aberto para novas mensagens.
  1. marco.luques

    marco.luques Membro Ativo

    Eu tenho feito for each apenas nos campos chaves ex it-codigo, e usando if para decidir os outros campos,

    ficou bem mais rápido...
    rhemati curtiu isso.
  2. bootstrapmaster

    bootstrapmaster Moderator Moderador Equipe de Suporte

    mas mesmo usando os campos chave, se não existe na base um codigo que vc está procurando, no for each é claro, ele demora pra te responder que não achou nada ou pra terminar o for each, esse é o problema, tanto que existe uma tecnica que é aconselhavel usar, por exemplo, vc quer ler o saldo de estoque dos estabelecimentos e deposito, normalmente o que fazemos ......
    Código:
                    put unformatted
                        ttResumo.cod-estabel[contador] ';'
                        ttResumo.serie[contador] ';'
                        ttResumo.nr-nota-fis[contador] ';'
                        ttResumo.quantidade[contador] ';'.
    
    Agora, pra ganhar performance, vc deve fazer assim ....
    Código:
    for each estabelecimento no-lock
        where estabelec.cod-estabel >= estabInicial
          and estabelec.cod-estabel <= estabFinal:
    
        for each deposito no-lock
            where deposito.cod-depos >= deposInicial
              and deposito.cod-depos <= deposFinal:
            for each  saldo-estoq no-lock
                where saldo-estoq.cod-estabel = estabelec.cod-estabel
                  and saldo-estoq.cod-depos   = deposito.cod-depos:
    
            end.
    
        end.
    end.
    
    Mas o que acontece, dependendo do que vc precisa, não dá diferença, então eu faço do primeiro jeito, que é mais facil de pensar na logica do processo, então eu faço a coisa acontecer e depois eu altero para ver se ganho performance.

    outro macete interessante é quando se trata de datas ......
    Código:
    for each movto-estoq no-lock
        where movto-estoq.dt-trans >= 01/01/2015
          and movto-esotq.dt-trans <= 01/31/2015:
    
    end.
    
    fica mais rapido se fizer ......
    Código:
    define variable dataTemp as date no-undo.
    
    repeat dataTemp = 01/01/2015 to 01/31/2015:
        for each  movto-estoq no-lock
            where movto-estoq.dt-trans = dataTemp:
        end.
    
    end.
    
    Mas eu repito, isso não é regra geral, depende muito do contexto do que vc está fazendo.

    Mas a minha idéia em relação ao topico do post é a questão de que um can-find, que só verifica se existe, sem retornar cache, buffer nem nada pode ser mais util do que sair direto em um for each, ou seja, vc só ir no for each na certeza de que vai encontrar o que precisa.
    rhemati curtiu isso.
  3. bootstrapmaster

    bootstrapmaster Moderator Moderador Equipe de Suporte

    Pessoal, no meu exemplo o primeiro codigo colei errado
    Código:
            for each  saldo-estoq no-lock
                where saldo-estoq.cod-estabel >= estabInicial
                  and saldo-estoq.cod-estabel <= estabFinal
                  and saldo-estoq.cod-depos   >= deposInicial
                  and saldo-estoq.cod-depos   <= deposFinal:
    
            end.
    
    rhemati curtiu isso.
  4. SAC

    SAC Membro Participativo

    Richard, é isso aí mesmo... o can-find só retorna a flag se existe ou não existe no banco, enquanto o find e o for each carregam a tabela inteira para a shared memory, ou seja, vai no disco e carrega para a memória e quanto maior o tamanho do registro da tabela, mais lento é.
    rhemati curtiu isso.
  5. rhemati

    rhemati Membro Participativo

    muito bom mesmo, tudo aqui postado. é isto aí, a experiência de todos sempre acrescenta.
  6. bootstrapmaster

    bootstrapmaster Moderator Moderador Equipe de Suporte

    Então, nos exemplos que citei, faltou colocar o can-find pra ficar melhor .... seguindo a logica do POST .....
    Código:
    for each estabelecimento no-lock
        where estabelec.cod-estabel >= estabInicial
          and estabelec.cod-estabel <= estabFinal:
    
        for each deposito no-lock
            where deposito.cod-depos >= deposInicial
              and deposito.cod-depos <= deposFinal:
            if can-find(first saldo-estoq where saldo-estoq.cod-estabel = estabelec.cod-estabel and saldo-estoq.cod-depos = deposito.cod-depos) then do:
                for each  saldo-estoq no-lock
                    where saldo-estoq.cod-estabel = estabelec.cod-estabel
                      and saldo-estoq.cod-depos   = deposito.cod-depos:
                end.
            end.
        end.
    end.
    
    e ....
    Código:
    define variable dataTemp as date no-undo.
    
    repeat dataTemp = 01/01/2015 to 01/31/2015:
        if can-find(first movto-estoq where movto-estoq.dt-trans = dataTemp) then do:
            for each  movto-estoq no-lock
                where movto-estoq.dt-trans = dataTemp:
            end.
    
        end.
    end.
    rlfritz curtiu isso.
Status do Tópico:
Não esta aberto para novas mensagens.

Compartilhe esta Página