Alternativa para não criar Lookup

Delphi

29/07/2009

Olá,

Gente o esquema é o seguinte, desenvolvi uma aplicação que acessa uma banco de dados mysql em um servidor remoto. Até aí tudo bem, o problema é que como está sendo utilizado em internet 3G, ele fica muito lento, pois demora pra gravar informações e buscar informações.

Eu gostaria de alguma dica que me ajude a deixa-lo mais rápido, por exemplo tipo tem como eu gerar um arquivo XML contento os dados de uma lookup e de tempos em tempos atualizar esse arquivo ou coisa assim?
Como posso fazer para criar uma opção do usuário trabalhar desconectado? o problema de trabalhar desconectado é que tem que criar um banco local e isso é um pouco inviável para o meu projeto.


qualquer dica já ajuda, agradeço pela atenção.


Daniel Martins

Daniel Martins

Curtidas 0

Respostas

Guinther

Guinther

29/07/2009

Daniel

Eu publiquei um artigo na ClubeDelphi 70 que mostra exatamente o que você precisa, eu baixo as tabelas lookup para o cliente, salvo em XML, e não busco mais no servidor. Abaixo um fragmento que explica a técnica:

[b:859925ce84]Cache no cliente em XML[/b:859925ce84]

Que campos Lookup não são mais utilizados há anos todo mundo sabe. Eles envolvem o fetch total dos dados de toda a tabela do banco de dados, o que em um ambiente DataSnap HTTP, ou mesmo client/server, vai comprometer todo o desempenho da solução. É muito melhor fazer um Join no servidor e fornecer uma pesquisa auxiliar para definir seu valor.
Porém, vamos justamente nos aproveitar dessa limitação e fazer o “lookup” jogar a nosso favor. Em nosso exemplo, todos os dados da tabela Department são recuperados cada vez que abrimos um registro. Porém, vamos analisar o seguinte: os dados dessa tabela raramente vão mudar no banco de dados, afinal, um departamento não é criado da noite pro dia em uma empresa.
O que vamos fazer é o seguinte: a primeira vez que o lookup for aberto, vamos fazer a consulta no banco. A seguir, vamos gravar essas informações em cache localmente, em um arquivo XML. Na segunda vez que a consulta lookup for aberta, buscaremos os dados do arquivo local ao invés de usar o servidor. Para isso, declare no formulário (ou Data Module local caso tenha criado) o método OpenCache.

procedure TForm1.OpenCache(ACds: TClientDataSet;
fn: string);
var
Ex: boolean;
d: TDateTime;
begin
{ Declare DateUtils no uses }
if FileExists(fn) then
begin
d := FileDateToDateTime(FileAge(fn));
ex := DaysBetween(now,d) > 3;
end
else
ex := True;
if Ex then begin
ACds.Open;
ACds.SaveToFile(fn);
end
else
ACds.LoadFromFile(fn);
end;

Ele é um método genérico, você pode passar qualquer ClientDataSet como parâmetro. Estou usando um mecanismo simples para fazer uma espécie de “expiração” de cache, ela ficará no disco por três dias. É claro, você pode personalizar a regra da expiração da cache, como por exemplo, detectando se houve uma mudança no BD ou usando uma flag que pode ser configurada a partir de um trigger que dispara quando a tabela for atualizada. Personalize esse mecanismo da melhor forma de acordo com a sua necessidade.
Como não estamos abrindo explicitamente o segundo ClientDataSet - tabelas lookups são abertas automaticamente pela VCL quando abrimos a consulta “mestre” - precisamos interceptar esse evento e fornecer o tratamento apropriado. Isso pode ser facilmente conseguido digitando-se o seguinte no evento BeforeOpen do primeiro ClientDataSet:

OpenCache(ClientDataSet2,´DEPARTMENT.XML´);

Execute a aplicação e veja que, após abrir um registro, será criado um arquivo local que contém os dados lookup em formato XML. Dessa forma, estamos refinando ainda mais o tráfego de dados, deixando uma possível solução HTML a quilômetros de distância no quesito performance e otimização.

Guinther Pauli
Delphi Certified: 3,5,6,7,2005,2006,Web,Kylix
http://guintherpauli.blogspot.com
http://twitter.com/guintherpauli


GOSTEI 0
Daniel Martins

Daniel Martins

29/07/2009

Aeee Guinther meu velho! Conterraneo de Santa maria..uehaueheau

Cara eu tenho essa edição porem esqueci em casa, eu me lembrei de que é possivel gerar uma xml, só nao lembrava detalhes... até procurei na web mas não achei, daí decidi postar pra ver se alguem tinha, e nao é que foi direto?! ehauehua

Mas eu tava analisando aqui o teu texto com a minha situação, no artigo vc cria uma um xml para listar a tabela ´Department´ que, como vc diz, não é da noite pro dia que vão criar um. No meu caso o programa possui uma tabela de Insumos (Materiais de Construção), em que cada vez que o usuário vai fazer o pedido o programa tem que mostrar uma lista conforme ele vai digitando, daí ele escolhe o mais adequado. Até fiz uma query Select id_insumo, descricao where descricao like(:descri), mas essa query faz muita requisição no servidor durante a digitação e isso deixa lento pra caramba..haeaeh

No caso de não existir o insumo no banco, o usuario digita por completo e na hora de enviar a solicitação o programa grava.

me pergunto se criar um xml realmente resolveria o problema... que vc acha?


GOSTEI 0
Guinther

Guinther

29/07/2009

Dr

Aí não tem como fazer cache. Uma boa prática é o seguinte, coloque seu código de pesquisa em um botão, com Enabled := false. No OnChanged do Edit, teste se o Lenght é maior ou = a 3, ou seja, o usuário tem que digitar no mínimo três letras para vc habilitar a pesquisa no banco. Se vc fizer essa pesquisa a cada tecla pressionada, vai ficar muito lento mesmo. Isso que mostrei é uma boa prática de programação, usando não só em aplicações desktop, mas Web, multicamadas etc.

Guinther


GOSTEI 0
Daniel Martins

Daniel Martins

29/07/2009

bom, é uma solução simples... mesmo assim não tem como fugir da requisição no banco.... considerando que depois de um certo tempo de uso daí talvez criar o xml seja mais viável, considerando que os materiais vão repetir no pedido..


GOSTEI 0
POSTAR