Página 5 de 7

Uso de letodb

Enviado: 14 Jun 2024 17:48
por leandrolinauer
Boa tarde.
Deu certo, consegui colocar os índices temporários na memória, até aí resolveu 50% do meu problema, arquivos temporários lixos que ficavam na pasta e tinha que ficar limpando direto, blz resolvido, nada de índices no disco fixo só na memória.
Segue o código em tanto para LETO como DBFCDX

Código: Selecionar todos

DbCreate("mem:"+"&LArquivo.",Campos,cDriver,.T.)
NewIndexFile(Chave ,cD_Tempo,"mem:"+LArquivo,aOd,.F.,,"MEMAREA") //INDEX ON
USE "mem:"+LArquivo ALIAS &LArquivo.  //abre o arquivo exclusivo
DbSetIndex("mem:"+LArquivo) //indexa todos os indices
Agora uma informação:
Achei que iria melhorar a velocidade colocando em memória, mas não resolveu.
Uma tabela de registro (produtos) buscando os dados nas tabelas das filiais relacionado cerca de 13 tabelas, para uma quantidade de registros de cerca de 8.000 de produtos cadastrados leva de 210 a 230 segundos para gravar no temporário o que se torna muito para quem esta puxando os dados todos, isto tratando de puxar a tabela toda de uma só vez, tanto faz em LETO e em memória o temporário como em DBFCDX em memória ou em DBFCDX em disco fixo, já em ARRAY este processo cai para cerca de 100 segundos, 50% de ganho na velocidade para capturar em temporários para mostrar na tela e manipular.
Em ARRAY, só peguei os dados, não editei pq não tenho um editor para MATRIZ.
Bom, não sei se pesquiso de forma errada ou ultrapassada, se existe algo diferente para ganho de velocidade, vi algo como SCOPE() só não consegui entender, ou seja, não utilizo SCOPE() no meu sistema.
Segue abaixo o um pedaço do trecho de pesquisa de produtos.

Código: Selecionar todos

Static Procedure New_BuscaProduto(oModo)
ShowWait(,,"Selecionando registros...")
DbSelectArea("CEST0300") //seleciono o principal aberto da loja
DbGoTop()
If Left(wMerc,2)#"99".And.SubStr(wMerc,3,2)#"99".And.Right(wMerc,3)=="999"
   DbSeek(Left(wMerc,4),.T.)
ElseIf Left(wMerc,2)#"99".And.Right(wMerc,5)=="99999"
   DbSeek(Left(wMerc,2),.T.)
ElseIf wMerc#"9999999"
   DbSeek(wMerc)
EndIf
While (!Eof()).And.If(Left(wMerc,2)#"99".And.SubStr(wMerc,3,2)#"99".And.Right(wMerc,3)=="999",Left(CODIGO,4)==Left(wMerc,4),;
                   If(Left(wMerc,2)#"99".And.Right(wMerc,5)=="99999",Left(CODIGO,2)==Left(wMerc,2),;
                   If(wMerc#"9999999",CODIGO==wMerc,.T.))).And.wSaida=.F.
	wSaida:=ExitSeek()
       ShowWaitProc()

	If (oGRUPO   =="9999".Or.GRUPO   ==oGRUPO).And.;
	   (oSUBGRUPO=="9999".Or.SUBGRUPO==oSUBGRUPO).And.;
      (oMARCA   =="9999".Or.MARCA   ==oMARCA).And.;
      (oMODELO  =="9999".Or.MODELO  ==oMODELO).And.;
      (oLINHA   =="9999".Or.LINHA   ==oLINHA).And.;      
      (oCLASSE  =="9999".Or.CLASSE  ==oCLASSE)
	   CEMP0000->(DbGoTop())
	   While CEMP0000->(!Eof())
        wSaida:=ExitSeek()
        ShowWaitProc()
        If If(o_Acao=6,CEMP0000->C_LOJA==wFilial,(wGEco=="99999999".Or.Left(CEMP0000->E_CGC,8)==wGEco).And.If(wLoja=="0001",.T.,wLoja==CEMP0000->C_LOJA)) 
           hE_CGC:=Left(CEMP0000->E_CGC,8)
           fP    :=CEMP0000->C_LOJA
           v_Merc:=CEST0300->CODIGO
           a_Area:="C300"+fP
           w_vTXT:=fP + " - " +v_Merc + " - " + CEST0300->DESCRICAO
           If o_Busca=.T. .And. (o_Acao=1 .Or. If(o_Acao=2,a_Area->P_VALOR>0,If(o_Acao=3,a_Area->DESCONTO>0,If(b_Acao=1,a_Area->BASICO="B",If(b_Acao=2,a_Area->BASICO#"B",If(b_Acao=3,.T.,If(c_Acao=1,a_Area->E_AT$" S",If(c_Acao=2,a_Area->E_AT=="N",If(c_Acao=4,ChkInC(),.T.)))))))))              	                                  	                    				        			     
            If If(o_Acao=6.And.v_Acao=1,a_Area->ATUAL>0,.T.)
                   (File1Tmp)->(DbAppend())
                   (File1Tmp)->LOJA     :=fP
                   (File1Tmp)->UF       :=CEMP0000->E_UF
                   (File1Tmp)->E_CGC    :=hE_CGC
                   (File1Tmp)->CODIGO   :=(a_Area)->CODIGO
                   (File1Tmp)->TICADO   :=" "
                   (File1Tmp)->E_AT     :=(a_Area)->E_AT
......demais campos necessarios
                 EndIf
              EndIf
           EndIf
        EndIf
		  CEMP0000->(DbSkip(1))
		End
	EndIf
	DbSkip(1)
End
CloseWindow()
Return Nil
Basicamente seria o codigo acima, bem limpo mas mesmo assim leva muito tempo para buscar a tabela toda de todas as lojas.

O que eu gostaria é de alguma forma rápida de pesquisa semelhante a SQL.
Pensei em abrir vazio e a pesquisa em threads para ir carregando o temporário, isto tomando uns cuidados de bloquear alterações enquanto não estiver totalmente carregada, seria a melhor forma?
Grato
Um abraço.

Uso de letodb

Enviado: 14 Jun 2024 19:30
por Itamar M. Lins Jr.
Olá!
Mais é isso que eu te falei, lá no inicio.
tinha que ficar limpando direto, blz resolvido, nada de índices no disco fixo só na memória.
Aqui vc ainda não entendeu. Arquivo temporário(dbf) é uma coisa e índice temporário é outra coisa.

Nesse ultimo exemplo não vai resolver pq vc fica fazendo "do while" em 2 tabelas Matriz x Filiais.
Então vc precisa fazer 2 "index temporary" pra ficar mais rápido.

Por exemplo:
CEST300 pode ter X incidencias. Separa aqui logo todas. 1 temporary. Se tiver 800 mil, vai cair pra 1 ou alguns poucos que satisfaçam a condição.
Depois se existir tal coisa -> grupo, subgrupo marca, modelo, linha, classe(...)
Entra em CEMP0000 -> aqui tem outro "DO WHILE" aqui -> (15 dbfs) If(o_Acao=6,CEMP0000->C_LOJA==wFilial,(wGEco=="99999999".Or.Left(CEMP0000->E_CGC,8)==wGEco).And.If(wLoja=="0001",.T.,wLoja==CEMP0000->C_LOJA))
Agora, vc monta um arquivo se for satisfeita essa condição:
If o_Busca=.T. .And. (o_Acao=1 .Or. If(o_Acao=2,a_Area->P_VALOR>0,If(o_Acao=3,a_Area->DESCONTO>0,If(b_Acao=1,a_Area->BASICO="B",If(b_Acao=2,a_Area->BASICO#"B",If(b_Acao=3,.T.,If(c_Acao=1,a_Area->E_AT$" S",If(c_Acao=2,a_Area->E_AT=="N",If(c_Acao=4,ChkInC(),.T.)))))))))

Vamos supor que são 100 filiais.
Pra dizer a pessoa, que o produto X tem na FILIAL Y
Da mesma forma que vc criou o indice na matriz é só criar para as filiais.
Primeiro criar o indice da Matriz -> sapara o que deseja, e faz a mesma coisa em cada filial, para depois jogar em um dbf na memoria.

PS.Rapaz tive que reler algumas vezes...
Entenda, tem 8 mil registros isso é pouco, desses 8 mil na matriz separo o que me interessa usando indice temporary e faço a mesma coisa nas filiais, em cada uma pego e jogo em um arquivo.
Separo antes, entendeu ? Depois uso um DO WHILE nele já separado.
Da sua forma no caso será "DO WHILE" em 8 mil x quantidade de filiais.(MAIS 8 mil)
Usando indice temporário vc SEPARA o que quer e pega. Vai pegar em bem poucos talvez em 1 só.

O índice temporário deixa de existir quando fecha o DBF. ou usar a função OrdDestroy() para apagar ele, caso não queira fechar e abrir novamente.

Saudações,
Itamar M. Lins Jr.

Uso de letodb

Enviado: 14 Jun 2024 19:49
por Itamar M. Lins Jr.
Olá!
Se vc não deseja usar indice temporary, achou complicado, basta fazer da mesma forma que fez na matriz usando dbseek(), vc não fez nas filiais, nas filias vc varre todo o DBF.

Essa parte vc não fez quando procura nas filiais.
DbGoTop()
If Left(wMerc,2)#"99".And.SubStr(wMerc,3,2)#"99".And.Right(wMerc,3)=="999"
DbSeek(Left(wMerc,4),.T.)
ElseIf Left(wMerc,2)#"99".And.Right(wMerc,5)=="99999"
DbSeek(Left(wMerc,2),.T.)
ElseIf wMerc#"9999999"
DbSeek(wMerc)
EndIf
PS.Se é que entendi o que vc quer.
PS2. Também não sei sei isso ai em cima, satisfaz todas as condições, caso contrário pega tudo mesmo.(melhor usar índice temporário)

Saudações,
Itamar M. Lins Jr.

Uso de letodb

Enviado: 14 Jun 2024 22:00
por leandrolinauer
Boa noite.
Esqueci de colocar aqui que lá na abertura dos arquivos e seus índices eu relacionei o arquivo produto de cada filial no da matriz, por isto não tem o seek na filial, só posiciono na matriz e o da filial já é posicionado no mesmo momento.
No cemp0000 é a relação das filiais e caminho das pastas e arquivos de cada uma, ou seja, eu separei a anos atrás por filial, mas agora já estou fazendo algumas junções em um único DBF, motivo, todos os dados estarão em todas as lojas, igualar o banco de dados.
Já está com sucesso o contas a pagar e dpto pessoal.
Estou aos poucos mudando pra não dar dor de cabeça e juntar tudo.
Próximo passo, clientes.
Bom, qto a pesquisa, pelo que entendi o arquivo temporário ele seria fixo, não apagaria, assim ele já existiria.
A demora ocorre pq estou varrendo a tabela toda pra pegar tudo, qdo quero só de um grupo, pesquiso só aquele grupo e sai mais rápido pq é menos dados.
O que eu estou pensando em fazer é abrir a central do produto acionar a pesquisa e já mostrar os primeiros dados enquanto a pesquisa trabalha em segundo plano enchendo o temporário com as informações pra edição da dos dados.
Algo assim mais ou menos, ou agilizar a captura dos dados pra editar.
A demora ocorre é no preenchimento do temporário.
Qdo gravo estes dados em array os 8.000 x as 10 lojas preenche bem mais rápido tipo 220 segundos contra 100 segundos.
Cai pela metade o tempo pra liberar pra editar os itens.

Uso de letodb

Enviado: 14 Jun 2024 23:15
por Itamar M. Lins Jr.
Olá!
Vc entendeu o que expliquei ?

Saudações,
Itamar M. Lins Jr.

Uso de letodb

Enviado: 15 Jun 2024 07:44
por leandrolinauer
Bom dia, creio que não entendi direito não.
"Nesse ultimo exemplo não vai resolver pq vc fica fazendo "do while" em 2 tabelas Matriz x Filiais.
Então vc precisa fazer 2 "index temporary" pra ficar mais rápido."
Eu preciso de uma tabela temporária só com os dados selecionados na pesquisa para serem manipulados, há uma outra forma de se fazer diferente da que eu estou acostumado a fazer que é:
1-Crio um arquivo e com indices desejados que será destruída, ou seja, lixo na pasta.
2-Seleciono os dados da tabela de origem, posicionando e fazendo um while até a condição não cumprir mais.
3-Mostro na tela com DBEDIT estes dados da tabela temporária.
Isto eu faço fisicamente criando lixo na pasta, atualmente esta desta forma ainda o que leva um tempão do inicio da pesquisa até aparecer os dados desejados.
Exemplos: edição de produtos, relatórios usuais, etc.

Depois da COVID fiquei mais dificil de compreender novas possibilidades.
Não consigo nem resolver um cubo mágico (rsrsrsrsrs) (idade rsrsrs).

Grato pela compreensão.

Uso de letodb

Enviado: 15 Jun 2024 10:30
por ivanil
bom dia,

não sou usuário do letodb, mas acredito que seu código precisa ser otimizado; fiz algumas anotações que pode ou não ser útil; é apenas uma ideia de alguém que não tem profundidade no seu código,
A solução do Itamar acredito ser a mais veloz, mas se puder ajustar partes das indicações abaixo já tera uma grande melhora no desempenho.

Nota: Vejo ser possível fazer outras otimizações, mas 1 passo de cada vez...

Código: Selecionar todos

Static Procedure New_BuscaProduto(oModo)
/*Otimizando seu código com variáveis locais*/

Local cMerc2 :=left(wMerc,2)
Local cMerc32:=substr(wMerc,3,2)
Local cMerc4 := left(wMerc,4)
Local cMerc5 := Right(wMerc,5)
Local cMercF :=Right(wMerc,3)
Local cChave,bChave,n1:=0

ShowWait(,,"Selecionando registros...")
/*melhorando a leitura de seu código para terceiros”
*DbSelectArea("CEST0300") //seleciono o principal aberto da loja
CEST0300->(DbGoTop())

If SubStr(wMerc,1,4)#"9999".And.cMercF=="999"
   CEST0300->(DbSeek(cMerc4,.T.))

ElseIf cMerc2#"99".And.cMerc5=="99999"
   CEST0300->(DbSeek(cMerc2,.T.))

ElseIf wMerc#"9999999"
   CEST0300->(DbSeek(wMerc))

EndIf
While (!Eof()).And.If(cMerc#"99".And.cMerc32 #"99".And.cMercF=="999",Left(CEST0300->CODIGO,4)==cMerc4,;
                   If(cMerc2#"99".And.cMerc =="99999",Left(CEST0300->CODIGO,2)==cMerc,;
                   If(wMerc#"9999999", CEST0300->CODIGO==wMerc,.T.))).And.wSaida=.F.

   wSaida:=ExitSeek()//essa função é chamada registro a registro, faz sentido manter ?
       *ShowWaitProc()//ShowWaitProc não pode ficar aqui, acredito ser o segundo maior problema.  
       *Para usar uma função que acompanha o processamento faça algo parecido onde n1 é uma variável local
       If(n1>500,(n1:=0, ShowWaitProc()),n1++)

   If (oGRUPO   =="9999".Or. CEST0300->GRUPO   ==oGRUPO).And.;
      (oSUBGRUPO=="9999".Or. CEST0300->SUBGRUPO==oSUBGRUPO).And.;
      (oMARCA   =="9999".Or. CEST0300->MARCA   ==oMARCA).And.;
      (oMODELO  =="9999".Or. CEST0300->MODELO  ==oMODELO).And.;
      (oLINHA   =="9999".Or. CEST0300->LINHA   ==oLINHA).And.;      
      (oCLASSE  =="9999".Or. CEST0300->CLASSE  ==oCLASSE)
      //você da um scan na tabela para cada registro, isso vai ficar pior a cada dia, crie índice
      *CEMP0000->(DbGoTop())
      If o_Acao=6
            CEMP0000->(DbSetorder(****))
            cChave := wFilial
            bChave := {|| CEMP0000->C_LOJA==wFilial}
      Else
            CEMP0000->(DbSetorder(****))
            cChave := wLoja
            bChave :={||(wGEco=="99999999".Or.Left(CEMP0000->E_CGC,8)==wGEco).And.If(wLoja=="0001",.T.,wLoja==CEMP0000->C_LOJA)}
      endif             
      CEMP0000->(DbSeek(cChave))
      While CEMP0000->(!Eof()).and.Eval(bChave)
        
        *wSaida:=ExitSeek() //essa função é chamada registro a registro, faz sentido manter ?
        *ShowWaitProc()//ShowWaitProc não pode ficar aqui, acredito ser o segundo maior problema.  
       *Para usar uma função que acompanha o processamento faça algo parecido onde n1 é uma variável local
       If(n1>500,(n1:=0, ShowWaitProc()),n1++)
        hE_CGC:=Left(CEMP0000->E_CGC,8)
        fP    :=CEMP0000->C_LOJA
        v_Merc:=CEST0300->CODIGO
        a_Area:="C300"+fP
        w_vTXT:=fP + " - " +v_Merc + " - " + CEST0300->DESCRICAO
        If o_Busca=.T. .And. (o_Acao=1 .Or. If(o_Acao=2,a_Area->P_VALOR>0,If(o_Acao=3,a_Area->DESCONTO>0,If(b_Acao=1,a_Area->BASICO="B",If(b_Acao=2,a_Area->BASICO#"B",If(b_Acao=3,.T.,If(c_Acao=1,a_Area->E_AT$" S",If(c_Acao=2,a_Area->E_AT=="N",If(c_Acao=4,ChkInC(),.T.)))))))))                                                                                                            
            If If(o_Acao=6.And.v_Acao=1,a_Area->ATUAL>0,.T.)
                   (File1Tmp)->(DbAppend())
                   (File1Tmp)->LOJA     :=fP
                   (File1Tmp)->UF       :=CEMP0000->E_UF
                   (File1Tmp)->E_CGC    :=hE_CGC
                   (File1Tmp)->CODIGO   :=(a_Area)->CODIGO
                   (File1Tmp)->TICADO   :=" "
                   (File1Tmp)->E_AT     :=(a_Area)->E_AT
......demais campos necessarios
                 EndIf
              EndIf
           EndIf
        EndIf
        CEMP0000->(DbSkip(1))
      End
   EndIf
   CEST0300->(DbSkip(1))
End
CloseWindow()
Return Nil



Uso de letodb

Enviado: 15 Jun 2024 11:19
por leandrolinauer
Bom dia Ivanil.
Realmente fica bem melhor pra interpretar, contudo não modifica a performance.
Fiz outro teste só pra analisar a velocidade.
Como havia passado, esta assim hoje.

1- DBFCDX arquivo temporário fixo gerado no disco, leitura da tabela toda em 220 segundos, muito e obsoleto.

2- LETO em memória arquivo gerado em memória mas com o mesmo desempenho do fixo 220 segundos, melhor que não gera arquivos no disco, vou optar por enquanto.

3- ARRAY gerando os DADOS em MATRIZ desempenho de 50% do desempenho acima cerca de 100 segundos.

4- Teste sem gravar os dados, apenas passando a tabela toda observando das condições mas não grava nada, levou 50 segundos, ou seja, só selecionando já consome um tempo bom, 1 minuto aguardando aparecer dados para um usuário é uma eternidade (rsrsrs).

5- Teste com ORDSCOPE() em uma tabela de dados é instantâneo e aparece os dados na sequencia do indice selecionado, gostei muito, estou partindo para isto, igual o Itamar falou.

Como pretendo usar o ORDSCOPE(), criarei os índices necessários na tabela original dos dados e irei pesquisar diretamente nela relacionando com tabela secundárias com os dados das filiais, tais como: estoque, preço, etc.
Com isto terei que alterar o fonte para mostrar os dados gerais em uma linha e tela, e em outra tela os dados deste item conforme as lojas, algo tipo em cima dados gerais e em baixo dados do item, algo assim pra caber na tela.

Posto resultados assim que conseguir esta proeza.
Valeu.
Grato

Uso de letodb

Enviado: 15 Jun 2024 19:46
por JoséQuintas
Fonte complicado.
LetoDB não otimiza filter?
Começa por aproveitar isso, no estilo de SQL, SEM VARIÁVEIS, assim o leto entende.
E fonte é pra programador, não é pra computador.
O outro DO WHILE... sei lá porque processa o arquivo completo pra cada registro....
Se é assim, talvez melhor se fosse o contrário, e ao invés de trocentas execuções, seria uma só.

Aliás....
"IF o_Busca=.T. .AND."
Que carvalho é esse ? vai processar o arquivo inteiro mesmo quando não vai usar pra nada?
Só se usa em outra parte do fonte que não está aí.
Complicar fonte, só complica manutenção... fazer o que...

Código: Selecionar todos

STATIC PROCEDURE New_BuscaProduto( oModo )

   LOCAL cFilter := ".T."

   DO CASE
   CASE Left( wMerc, 2 ) != "99" .AND. Substr( wMerc, 3, 2 ) != "99".And. Right( wMerc, 3 ) =="999"
      cFilter += [ .AND. Left( CODIGO, 4 ) == "] + LEFT( wMerc, 4 ) + ["]
   CASE Left( wMerc, 2 ) # 99 .AND. Right( wMerc, 5 ) === "99999"
      cFilter += [ .AND. Left( CODIGO, 2 ) == "] + LEFT( wMerc, 2 ) + ["]
   CASE wMerc != "99999999"
      cFilter += [ .AND. CODIGO == "] + CODIGO + ["]
   ENDCASE
   IF oGrupo != "9999"
      cFilter += [ .AND. GRUPO == "] + oGrupo + ["]
   ENDIF
   IF oSubGrupo != "9999"
      cFilter += [ .AND. SUBGRUPO == "] + oSubGrupo + ["]
   ENDIF
   IF oMarca != "9999"
      cFilter += [ .AND. MARCA == "] + oMarca + ["]
   ENDIF
   IF oModelo != "9999"
      cFilter += [ .AND. MODELO == "] + oModelo + ["]
   ENDIF
   IF oLinha != "9999"
      cFilter += [ .AND. LINHA == "] + oLinha + ["]
   ENDIF
   IF oClasse != "9999"
      cFilter += [ .AND. CLASSE == "] + oClasse + ["]
   ENDIF

   ShowWait(,,"Selecionando registros...")
   DbSelectArea("CEST0300") //seleciono o principal aberto da loja

   SET FILTER TO &(cFilter)
GOTO TOP

   DO WHILE CEST300->( ! Eof() ) .AND. ! wSaida

      wSaida := ExitSeek()

      ShowWaitProc()

      CEMP0000->(dbGoTop())
      DO WHILE CEMP0000->(!Eof())
         wSaida:=ExitSeek()
         ShowWaitProc()
         IF If(o_Acao=6,CEMP0000->C_LOJA==wFilial,(wGEco=="99999999".Or.Left(CEMP0000->E_CGC,8)==wGEco).And.If(wLoja=="0001",.T.,wLoja==CEMP0000->C_LOJA))
            hE_CGC:=Left(CEMP0000->E_CGC,8)
            fP    :=CEMP0000->C_LOJA
            v_Merc:=CEST0300->CODIGO
            a_Area:="C300"+fP
            w_vTXT:=fP + " - " +v_Merc + " - " + CEST0300->DESCRICAO
            IF o_Busca=.T. .AND. (o_Acao=1 .OR. If(o_Acao=2,a_Area->P_VALOR>0,If(o_Acao=3,a_Area->DESCONTO>0,If(b_Acao=1,a_Area->BASICO="B",If(b_Acao=2,a_Area->BASICO#"B",If(b_Acao=3,.T.,If(c_Acao=1,a_Area->E_AT$" S",If(c_Acao=2,a_Area->E_AT=="N",If(c_Acao=4,ChkInC(),.T.)))))))))
               IF If(o_Acao=6.And.v_Acao=1,a_Area->ATUAL>0,.T.)
                  (File1Tmp)->(DbAppend())
                  (File1Tmp)->LOJA     :=fP
                  (File1Tmp)->UF       :=CEMP0000->E_UF
                  (File1Tmp)->E_CGC    :=hE_CGC
                  (File1Tmp)->CODIGO   :=(a_Area)->CODIGO
                  (File1Tmp)->TICADO   :=" "
                  (File1Tmp)->E_AT     :=(a_Area)->E_AT
                  ......demais campos necessarios
               ENDIF
            ENDIF
         ENDIF
         CEMP0000->(dbSkip(1))
      ENDDO
      SKIP
   ENDDO
   CloseWindow()

   RETURN Nil
Nota:
Em SQL seria parecido com isso também, só colocar no WHERE do SQL.

Uso de letodb

Enviado: 15 Jun 2024 20:08
por leandrolinauer
Boa noite, é que os arquivos de produtos é um pra cada loja, aí eu utilizo o cemp0000 aonde estão os dados das lojas pra buscar os arquivos em suas pastas, só pra isto.
Estou alterando este fonte antigo pra um novo otimizado.
A variável busca é somente pra um teste temporário, ela não existe mais.
Sobre o set filter, a uns bons 25 anos atrás eu utilizei ele no Clipper ainda e não gostei, travava muito e acabei abandonando ele de vez, no harbour ele tem uma performance melhor?, vou testar da forma que passou pra ver se melhora.

Uso de letodb

Enviado: 15 Jun 2024 20:23
por JoséQuintas
leandrolinauer escreveu:no harbour ele tem uma performance melhor?, vou testar da forma que passou pra ver se melhora.
O tópico é de leto.
Não tem nada a ver com harbour.
Ou otimiza pra uma coisa ou pra outra.

Uso de letodb

Enviado: 17 Jun 2024 14:23
por JoséQuintas
Esqueci de comentar o principal:

As otimizações são só pra atualizações parciais.
Se é atualização total, não tem o que fazer.

SET RELATION pra atualização parcial, não é uma boa opção, porque vai pesquisar até o que não usa.
Não sei se leto aceleraria nesse caso, porque pode ser necessário fazer a pesquisa do relacionamento antes de comparar com o filtro, que pode conter dados de mais de um alias.

Uso de letodb

Enviado: 17 Jun 2024 14:40
por Itamar M. Lins Jr.
Olá!
O tópico é de leto.
Não tem nada a ver com harbour.
Ou otimiza pra uma coisa ou pra outra.
Essa parte não tem a ver com LetoDB.
Já disse pra ele o que fazer. Infelizmente ele não entendeu.
Criar indice temporário antes de fazer DO WHILE.
Separar antes, pra não precisar ficar varrendo o DBF todo, mas ele disse que usar RELATION... AI eu não sei pq não uso isso desde muito tempo.

Saudações,
Itamar M. Lins Jr.

Uso de letodb

Enviado: 17 Jun 2024 15:09
por Itamar M. Lins Jr.
Olá!
Tá relacionando 8 mil itens x 10 filiais. 80 mil itens... Não sei não vi o código.
Eu faço isso só que com INDEX FOR TEMPORARY e é quase instantâneo para 12 meses, em media 10 mil registros por mês.

Saudações,
Itamar M. Lins Jr.

Uso de letodb

Enviado: 17 Jun 2024 16:01
por JoséQuintas
Se processa tudo, pesquisa tudo..... o relacionamento serve pra que ?
Sei lá....