Página 1 de 1
SET FILTER NO BLINKER ***URGENTE****
Enviado: 23 Ago 2007 14:08
por managercorp
AS MESMAS LINHAS ABAIXO FUNCIONAM PERFEITO QUANDO COMPILO COM EXOSPACE, MAS QUANDO COMPILO COM BLINKER, A PESQUISA TRAVA EM UM DETERMINADO REGISTRO E NAO SAI NEM COM ALT+C
*******************
#Include "INKEY.CH"
#INCLUDE "SET.CH"
ANNOUNCE RDDSYS
REQUEST DBFCDX
RDDSETDEFAUT("DBFCDX")
CLEAR
SELE 9
use reserva SHARED
set index to reser1
SET FILTER TO (STATUS='1' .OR. STATUS='6')
SET ORDER TO 2
GO TOP
DO WHILE .NOT. EOF()
@ 23,00 SAY RECNO()
SKIP
ENDDO
***************************
AGORA SE EU TIRAR A LINHA DO SET FILTER, AI ELA PASSA OK
SERA QUE EXISTE IMCOMPATIBILIDADE DO BLINKER COM O SET FILTER
Enviado: 23 Ago 2007 14:45
por Maligno
A máquina trava ou fica tão lento que *parece* que trava? Por acaso não é aquele mesmo banco de dados com mais de 1 milhão de registros? Se for, não espere outra coisa do SET FILTER se não a lentidão. Esse tipo de filtro pode perfeitamente se tornar inviável em um volume de dados muito grande, já que ele faz o ponteiro do arquivo pular de registro a registro, do começo ao fim. Uma solução pra essa lentidão é limitar o escopo do trabalho do SET FILTER usando SET SCOPE.
Em tempo: não existe qualquer tipo de incompatibilidade do BLinker com o comando SET FILTER. Nem poderia.
PS: Uma dica: quando em comunicação via texto (chat, eMail, fórum, etc) só se utiliza letra maiúsculas quando se quer GRITAR com alguém.
Enviado: 23 Ago 2007 15:05
por managercorp
Ok Maligno
mas o travamento se dar depois da linha do set filter e sim dentro do do while
pelo que sei a demora seria pra sair do set filter
so que ele passa por essa linha e dentro do do while e que trava
. agora se pego essa mesma rotina e compilo com exospace o erro nao acontece
Enviado: 23 Ago 2007 16:13
por Maligno
Não, a demora começa no ponto em que o ponteiro se mexe. O comando SET FILTER apenas e tão somente configura o filtro. Ou seja, a coisa começa mesmo no GO TOP. Depois, na malha, você vai pegando registro a registro com o SKIP, conforme esse filtro. O problema pode ficar feio mesmo quando o registro atual é o último que satisfaz o filtro. Aí, supondo que no meio de 1 milhão de registros, o último encontrado, nas condições do filtro, é o de número 100.000, internamente o próximo SKIP vai provocar a leitura de 900.000 registros. Isso é obrigatório. Ele forçosamente tem de ir até o final do arquivo. Aí se explica a lentidão.
O que eu acabei de explicar é mandatório. Isso vai acontecer, não importa com qual linker você trabalhe. É a característica básica do comando SET FILTER. Ele sempre vai navegar por todo o arquivo, nas condições em que você mostrou que o utiliza.
Agora, porque isso não acontece quando se usa o ExoSpace, pra mim é um total mistério. Não sei o que dizer. :[
Enviado: 23 Ago 2007 16:19
por managercorp
Obrigado pela explicacao.
Mas se nao for pedir demais, sabes me explicar porque com o exospace
funciona uma bala.
Enviado: 23 Ago 2007 17:43
por Maligno
Pois não acabei de dizer que pra mim é um mistério?

Enviado: 24 Ago 2007 11:53
por Augusto
Parceiro "managercorp"... Experimente alterar a rotina e veja se fica mais rápido:
Código: Selecionar todos
SELE 9
use reserva SHARED
set index to reser1
SET ORDER TO 2
DO WHILE .NOT. EOF()
IF (STATUS='1' .OR. STATUS='6')
@ 23,00 SAY RECNO()
ENDIF
SKIP
ENDDO
Uma outra opção, já que o arquivo tem mesmo 1 mulhão de registro, é vc criar um arquivo temporário dando um APPEND somente dos registros que atendam a "condição" e depois listar todo o arquivo temporário...
Quanto ao "suposto" travamento não acontecer com o EXOSPACE eu acho muito difícil... Talvez ele nem esteja fazendo o SET FILTER, caso contrário... como diz o Maligno... "MISTÉRIO" !!!
Enviado: 24 Ago 2007 12:01
por Maligno
Teoricamente seu código teria de rodar mais lento ainda, já que o SET FILTER faz exatamente isso com comandos internos. Claro que não custa tentar.

Mas se fosse o caso de mudar algo radicalmente, eu sugeriria a criação de um índice temporário. Ou então, melhor ainda, a criação de um índice a mais (tag) com uma condição tal que permita a diminuição do volume de dados pesquisados (SET SCOPE), dentro do qual o SET FILTER certamente ficará rápido, se não instantâneio. Essa é, aliás, a forma como eu faço.
Enviado: 24 Ago 2007 12:20
por Augusto
Prezado Maligno,
Desculpe discordar, mais por experiência própria, ousei em dar a opção do IF pois, comigo funcionou ou seja, ficou mais rápido que o SET FILTER apesar de, posteriormente, ter optado pela crição do arquivo temporádio e mantenho esse procedimento quando necessário...
Na época, assim como vc, entendia que não havia diferença entre o IF e o SET FILTER mas fiz o teste e comprovei...
Enviado: 24 Ago 2007 12:33
por Maligno
Justamente pela falta de teste que usei a expressão "teoricamente seu código teria de rodar mais lento". Mas se você já fez o teste, fica então uma alternativa a mais pro colega. Se bem que, se o arquivo tiver mesmo mais de 1 milhão de registros, o ganho não deve ser tão grande. Fora isso, tem a questão do Exospace. Um total mistério.

Enviado: 24 Ago 2007 15:31
por managercorp
Pois e pessoal aqui abaixo vai exatamente o que estou usando e no exospace e instananeo e no blinker fica inviavel, quanto ao arquivo ele tem mesmo 1 milhao de registro.
aqui vai minha rotina, se alguem puder fazer isso diferente, eu agradeço muito.
********
SELE 9
SET FILTER TO (STATUS='1' .OR. STATUS='6' .OR. STATUS='5' .OR. STATUS='8') .AND. (WDATA >=DATACHE .AND. WDATA <DATAPAR)
SET ORDER TO 2
GO TOP
DO WHILE .NOT. EOF()
IF WDATA >= DATACHE .AND. WDATA < DATAPAR .AND. EMPRESA=XEMP
if status='1'
* aqui entra meu resultado *
endif
if status='6'
* aqui entra outro resultado *
endif
if status='5'
* aqui entra outro resultado *
endif
if status='8'
* aqui entra outro resultado *
endif
skip
enddo
********************************
NOTEM QUE PRECISO APENAS DOS STATUS 1,6,5 E 8 E DENTRO DA DATA EM QUESTAO
- Existe no arquivo varios outros status inclusive o status 3 que e a maioria e nao preciso passar por ele, por isso sempre usei o set filter
Agora que preciso migrar pro blinker, o set filter fica inoperante,
To PERDIDO, ao sei mas o que fazer.
se tivesse um jeito de indexar por condicao seria otimo.
Enviado: 28 Ago 2007 21:34
por andrethomazi
o set order to 2 dentro de um set filter não seria meio estranho? suponhamos que o set filter tenha "marcado" 50 000 registros da condicao especificada, quando vc mudaria a ordem de pesquisa do set order o que aconteceria com os filtrados? teriam que ser novamente filtrados ou marcados, pro ponteiro saber quais seriam as posicoes dos registros marcados. Experimente por o Set Order antes de filtrar os dados.....
Em meus programas (principalmente em rede), substitui todos os SET FILTERs por:
do while condição
se nao atender a condicao
skip
loop
fim do se
lista, processa, etc
skip
loop
enddo
Enviado: 29 Ago 2007 01:00
por Maligno
suponhamos que o set filter tenha "marcado" 50 000 registros da condicao especificada
O comando SET FILTER não marca registro algum. Através dele só se configura a condição de filtragem. Você só saberá quais registros satisfarão a condição do filtro depois de percorrer TODO o banco de dados. Portanto, o SET ORDER não fará diferença alguma, a não ser na ordem em que os registros serão acessados.