Página 2 de 4

Apagar um indice TEMPORARY

Enviado: 28 Jul 2016 14:50
por JoséQuintas
Só recapitulando o que lembro do mem:

1. Tem um recurso, aonde dois pontos no nome do arquivo tem um uso especial, não sei se tem a ver com Windows ou com NTFS
2. No Harbour, mem:arquivo significa temporário, desde que seja adicionada alguma coisa
3. Nos exemplos de uso de mem:, lembro de ter visto pra excluir no final, o que significa que ou está ocupando memória ou disco

Como no #define de TEMPORARY tem uma indicação de MEM:, pode estar relacionado.

Código: Selecionar todos

#command INDEX ON <key> [TAG <(tag)>] TO <(bag)> ;
               [FOR <for>] [WHILE <while>] [NEXT <next>] ;
               [RECORD <rec>] [<rest:REST>] [<all:ALL>] ;
               [EVAL <eval>] [EVERY <every>] [<unique: UNIQUE>] ;
               [<ascend: ASCENDING>] [<descend: DESCENDING>] ;
               [<add: ADDITIVE>] [<cur: USECURRENT>] [<cust: CUSTOM>] ;
               [<noopt: NOOPTIMIZE>] [<mem: MEMORY, TEMPORARY>] ;
               [<filter: USEFILTER>] [<ex: EXCLUSIVE>] => ;
         ordCondSet( <"for">, <{for}>, [<.all.>], <{while}>, ;
                     <{eval}>, <every>, RecNo(), <next>, <rec>, ;
                     [<.rest.>], [<.descend.>],, ;
                     [<.add.>], [<.cur.>], [<.cust.>], [<.noopt.>], ;
                     <"while">, [<.mem.>], [<.filter.>], [<.ex.>] ) ;;
         ordCreate( <(bag)>, <(tag)>, <"key">, <{key}>, [<.unique.>] )
igual usar net: no nome dos arquivos, de nada adianta se não linqueditar hbnetio.

Apagar um indice TEMPORARY

Enviado: 28 Jul 2016 14:56
por asimoes
Pessoal,

Fiz um teste sem usar o hbnetio, os índices temporários são criados na pasta temp do usuário, o teste que eu fiz criou o índice hb5BD9.tmp com 0 kb
Quando eu fechei a tabela o índice foi deletado.

Apagar um indice TEMPORARY

Enviado: 28 Jul 2016 15:07
por rubens
Gente seguiinte...

Para usar certinho tem que inserir o hbmemio...

Segundo... para apagar o indíce temporário... você não pode estar posicionado nele... e é o que eu realmente tava fazendo...
Dbsetorder(5)
OrdDestroy(5) -- e descobri também que no OrdDestroy também aceita o número e não somente o nome da TAG...

Daí é só posicionar fora da TAG que você quer apagar e mandar apagar...

Esse problema tá resolvido... hehe..

Vamos ver o próximo...

Obrigado
Rubens

Apagar um indice TEMPORARY

Enviado: 28 Jul 2016 15:37
por asimoes
É isso isso ai Rubens, até eu aprendi com isso.

Apagar um indice TEMPORARY

Enviado: 28 Jul 2016 18:15
por JoséQuintas
Legal, minha cabeça ainda funciona, lembrava que tinha que adicionar alguma coisa.

Só resta saber se precisa liberar a área da memória onde foi criado o temporário, ou se isso vai ser automático.

ASimões, se puder fazer o teste também com temporário em C:, pra comparar aquele seu arquivo de 1 milhão de registros....

Apagar um indice TEMPORARY

Enviado: 28 Jul 2016 18:20
por asimoes
Quintas,

Verifiquei o indice é criado na pasta temp do usuário com tamanho 0kb e é deletado quando a tabela é fechada.

Apagar um indice TEMPORARY

Enviado: 28 Jul 2016 18:27
por asimoes
Quintas,

O código do meu teste é esse:

Código: Selecionar todos

      nSecIni:=Seconds()
      aStru:={}
      aAdd(aStru, {"Codigo", "C", 10, 0})
      DbCreate("mem:teste", aStru, "DBFCDX", .T., "teste")
      
      FOR I:=1 TO 1000000
         TESTE->(DbAppend())
         TESTE->Codigo := StrZero(I, 10)
      NEXT
      
      INDEX ON CODIGO TAG CODIGO TEMPORARY ADDITIVE
      
      Alert(SecToTime(Seconds()-nSecIni))

Resultado:
Screen Shot 07-28-16 at 06.27 PM.PNG
Screen Shot 07-28-16 at 06.27 PM.PNG (4.59 KiB) Exibido 3390 vezes

Apagar um indice TEMPORARY

Enviado: 28 Jul 2016 18:45
por asimoes
Além de usar hbmemio.hbc tem que fazer o REQUEST HB_MEMIO

Apagar um indice TEMPORARY

Enviado: 12 Mar 2017 15:49
por fladimir
Simulei o exemplo do Rubens..

Abri a tabela Clientes ( a minha tem 9 chaves )

Fiz o Alert mostrou cada TAG 1 - Codigo, 2 - Nome.... 9 - Referencia

Fiz um:

Código: Selecionar todos

INDEX ON NASCIMENTO TAG TEMP ADDITIVE TEMPORARY
Mandei listar novamente as Chaves e mostrar no Alert()
Mostrou agora 10 sendo a última Nascimento

Ok até aki blz

Dúvida...

Fiz um DBCLOSEALL()

Abri novamente a tabela e mandei listar as chaves... listou 10 sendo q a última foi TEMPORARY não tinha q ao fechar ter excluido ela e qdo abri novamente mostrado 9 apenas?

Ai o Rubens comentou o seguinte...
Para usar certinho tem que inserir o hbmemio...

Segundo... para apagar o indíce temporário... você não pode estar posicionado nele... e é o que eu realmente tava fazendo...
Dbsetorder(5)
OrdDestroy(5) -- e descobri também que no OrdDestroy também aceita o número e não somente o nome da TAG...

Daí é só posicionar fora da TAG que você quer apagar e mandar apagar...
Como assim usar o HBMEMIO nisso? Eu tenho no meu código o HBMEMIO em alguns lugares pra criação de tabelas temporárias, mas o q tem haver isso com eu criar uma Chave/Indice Temporário com ADDITIVE TEMPORARY?

Apagar um indice TEMPORARY

Enviado: 12 Mar 2017 23:15
por rubens
Fladimir...

Não reli o tópico inteiro... mas pelo que me lembro na época... os índices temporários não são tão temporários assim... são criados na pasta temp do windows... inclusive numa postagem recente perguntei pro Asimoes onde encontra esta pasta porque eu não tinha localizados os arquivos temporários gerados... achei que eram gerados na memória mas, são gerados em disco nesta pasta temporária.. Daí a razão de usar hbmemio para a correta manipulação de aquivos temporários na "memória".
É o que eu entendi...
De qualquer forma está funcionando e beleza e rápido...
Antes quando precisava de um relatório com uma filtragem complexa que não dá para usar o ordscope seguido do set filter eu abria o arquivo, usava o set index to criava o novo índice e setava e esse novo indice imprimia o relatório e abria o arquivo de indice "físico" novamente... set index to indice...
Agora só crio o indice com o additive quando termino o relatório mudo a ordem do indice e apago o indice temporário na memória...
Não sei qual a razão do arquivo criado na pasta temporária que com o Asimoes mesmo disse tem o tamanho 0. Não sei qual a ligação, mas é perceptível que o indice tá trabalhando na memoria e na máquina local pela velocidade que é processado... é praticamente instantâneo...
Não corri atrás para entender totalmente a lógica da coisa... o importante é que tá funfando...

Rubens

Apagar um indice TEMPORARY

Enviado: 12 Mar 2017 23:57
por fladimir
Rubens, obrigado pelo retorno... veja o exemplo abaixo

Código: Selecionar todos

REQUEST HB_MEMIO
FUNCTION TesteIdxTmp // Rubens Topic 17412 Apagar Indice Temporary

 Use Clientes.DBF  alias Cli New Share
 cTEXTO := ''
 FOR X = 1 TO OrdCount()
  DbSetOrder(X) 
  cTEXTO += STR(X,2)+'-'+ORDKEY(INDEXORD()) + HB_EOL()
 NEXT
 Alert( cTexto ) //------------> Mostrou 9 Chaves
 
 DbSetOrder(2)
 DbGoTop()
 Browse()
 
 Index on NASCIMENTO TAG TEMP ADDITIVE TEMPORARY //----> Criou a 10ª chave teoricamente temporária

 cTEXTO := ''
 FOR X = 1 TO OrdCount()
	DbSetOrder(X) 
	cTEXTO += STR(X,2)+'-'+ORDKEY(INDEXORD()) + HB_EOL()
 NEXT
 Alert( cTexto ) //----------------------> Mostrou as  10 chaves lembrando q a útlima foi criada TEMPORARY

 //DbSetOrder(5)                                  //---> comentei essa parte pq queria ver o comportamento depois do DBCLOSEALL
 //OrdDestroy( ORDKEY(INDEXORD()) ) 

 DbCloseall()  //------------------------------> FECHEI TUDO

 Use ClienteS.DBF  alias Cli New Share
 cTEXTO := ''
 FOR X = 1 TO OrdCount()
  DbSetOrder(X) 
  cTEXTO += STR(X,2)+'-'+ORDKEY(INDEXORD()) + HB_EOL()
 NEXT
 Alert( cTexto ) //-----------------------------> Repeti o processo e note q o HBMEMIO foi requisitado, não teria q ter apagado no DBCLOSEALL o índice temporário????
RETURN NIL                                               //---> Esta com o REQUEST HBMEMIO q pelo q entendi da explicação faz na memória funcionar etc e ficar mais rápido mas não funciona a parte de apagar o ultimo indice temporário , somente se mudar de ordem na área e apagar a q foi criada??? É isso mesmo???

Apagar um indice TEMPORARY

Enviado: 13 Mar 2017 07:19
por rubens
Bom dia...

Então Fladimir...
No meus testes aqui ele não apaga sozinho...
Já que tá engatilhado aí... faz um teste... Muda de ordem antes de dar um dbcloseall...
Tem umas coisas estranhas... tinha que apagar sim... mas pelo menos nos meus testes não apagou o indice automaticamente...

Rubens

Apagar um indice TEMPORARY

Enviado: 13 Mar 2017 10:41
por fladimir
Testei aki e mesmo mudando a ordem antes do dbcloseall() qdo abrimos novamente e mandamos listar as chaves a bendita "temporária" esta lá

O q conclui-se então é q "Es temporaria pero no mucho...".kkkk

Tipo faz alguma coisa temporária mas deixa um pézinho físico, como se fosse tipo uma memória SWAP do Linux.

Então pra resolver, ou seja, ter o desempenho melhor do chamado "temporário", velocidade, usamos o procedimento, mas ao final tem q MUDAR de Ordem e Destruir a "Temporária"

Ao meu ver esta errado, pq no manual do comando fala q qdo o índice é fechado é apagado este indice temporário, o q não ocorre na prática, como faço pra sugerir uma revisão disto?

Apagar um indice TEMPORARY

Enviado: 13 Mar 2017 12:01
por fladimir
Com relação a precisar do HB_MEMIO tenho minhas dúvidas..

Pq no manual não menciona q pra usar o TEMPORARY tem q compilar junto o HB_MEMIO

Ai fiz alguns testes...

Criei uma tabela de cerca de 1 GB baseada em uma outra q fui criando copia e fazendo append da mesma, contendo 3.437.344 de registros

Ai fiz um teste com DBSETFILTER e outro com INDEX ON ... TEMPORARY

Segue abaixo

Código: Selecionar todos

function TstDesempenho()
   local nTotal := 0
   Use ConRec.dbf Alias ConRec New Share
   cTexto := ''
   FOR X:=1 TO ORDCOUNT()
      DBSETORDER(X)
      CTEXTO += STR(X, 2 ) + ' - ' + ORDKEY(INDEXORD()) + HB_EOL()
   NEXT
   ALERT(cTexto) // --> aki vemos q tem 12 Chaves...

   nSecIni := Seconds()
   dbsetfilter( { || ConRec->Cancelado == 'S' } )
   dbgotop()
   while !EOF()
       ntotal += ConRec->Valor
       skip
   end
   Alert( SecToTime(Seconds() - nSecINI) + ' ' + str(ntotal))
   //--> Resultado em 36 segundos

   //--> Repetindo o teste com IDX Temporario SEM HB_MEMIO
   nTotal := 0
   dbcloseall()
   Use ConRec.dbf Alias ConRec New Share
   cTexto := ''
   FOR X:=1 TO ORDCOUNT()
      DBSETORDER(X)
      CTEXTO += STR(X, 2 ) + ' - ' + ORDKEY(INDEXORD()) + HB_EOL()
   NEXT
   ALERT(cTexto) // --> aki vemos q tem 12 Chaves...

   nSecIni := Seconds()
   INDEX ON RECNO() TAG TEMP FOR CONREC->CANCELADO == 'S' ADDITIVE TEMPORARY
   dbgotop()
   while !EOF()
       ntotal += ConRec->Valor
       skip
   end
   Alert( SecToTime(Seconds() - nSecINI) + ' ' + str(ntotal))
   //--> Resultado em 27 segundos

  *-- Mostrando a bendita
  cTexto := ''
   FOR X:=1 TO ORDCOUNT()
      DBSETORDER(X)
      CTEXTO += STR(X, 2 ) + ' - ' + ORDKEY(INDEXORD()) + HB_EOL()
   NEXT
   ALERT(cTexto) // --> aki vemos q tem 13 Chaves... sendo a ultima a temporaria
  
   *-- Eliminando ela
   nOrdTmp := IndexOrd()
   cTagTmp := ordName(nOrdTmp)
   DbSetOrder(1)
   OrdDestroy( cTagTmp)
   
   dbCloseall()
return
Depois refiz o teste coloando no inicio REQUEST HB_MEMIO e compilando com HBMEMIO.hbc e o resultado foi em 26 segundos...

Fiz 4 x os testes e apresentou mesmos resultados

Com DBSETFILTER 36 segundos
Index On .. Temporary Additive SEM HB_MEMIO 27 segundos
Index On .. Temporary Additive COM HB_MEMIO 26 segundos

Agora faltou testar jogando para um novo arquivo de indice temporario sem ser ADDITIVE

Apagar um indice TEMPORARY

Enviado: 13 Mar 2017 12:29
por Kapiaba
Fladimir,

Código: Selecionar todos

GO TOP
? seconds()
INDEX ON field->ref TAG REF TO TEMP TEMPORARY
? seconds()
Para fechar o TEMPORARY/MEMORY basta:

Código: Selecionar todos

SET ORDER TO 0
Pertence a biblioteca: DBFCDX.LIB

Abs