Fórum ZeosLib SQL Server 6 milhoes de reg #372221
14/07/2009
0
Tanto o ADO como o ZeosLib acontece o msm problema.
Alguem sabe como faço para que ele nao aloque td na memoria? Ja tentei procurar por parametros mas nao achei nada.
Maker
Curtir tópico
+ 0Posts
14/07/2009
Lightshine
É uma alternativa já que, vc não precisará dos 6 milhões de registros naquele momento, vc pode executar um filtro trazendo o mínimo de registros possível para a sua instância, eliminando assim o consumo excessivo de recursos da maquina.
Lightshine
Gostei + 0
14/07/2009
Maker
Estou chegando a conclusao que eh uma limitacao dessas 2 bibliotecas (ADO e ZeosLib).
Gostei + 0
14/07/2009
Woinch
Espero ter ajudado.
Gostei + 0
14/07/2009
Osocram
pois se alguma maquina cliente que usar isso não tiver mta RAM vai zicar geral mano.
seria interessante fazer oq a Lightshine comentou.
outra coisa que vai influenciar tbm é se o seu sistema é em 3 ou 2 camadas.
Flw.
Gostei + 0
16/07/2009
Maker
Vou dar uma olhada sobre essa propriedade PacketRecords.
Alguem mais tem alguma idéia?
Gostei + 0
16/07/2009
Lightshine
Boa noite maker,
Já pensou em criar uma Thread para executar esta tarefa?
Talvez seja uma opção...
Porém se vc detalhar melhor o que quer fazer e como está fazendo, copiando os códigos usados, fica mais fácil para entendermos sua necessidade e tentarmos ajudá-lo da melhor forma possivel.
Lightshine
Gostei + 0
17/07/2009
Maker
mto obrigado pela atenção. Estou postando um codigo como exemplo do q ocorre. O problema ocorre qdo se tenta retorna mtos registros (no meu caso 6 milhoes). Qdo se executa ´Dataset.Open;´ o programa para esperando a resposta do servidor. Dps de alguns segundos nota-se a movimentação de pacotes na rede e a memória subindo e subindo... e fica só nisso.
Gostei + 0
17/07/2009
Maker
unit testesqlserver;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls,ZConnection, ZDataset,ZDbcIntfs;
type
TForm1 = class(TForm)
Button1: TButton;
Memo1: TMemo;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
Connection: TZConnection;
Dataset: TZReadOnlyQuery;
arq: textfile;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
var
i,j: integer;
s,linha: string;
begin
Connection := TZConnection.Create(nil);
Connection.Protocol := ´mssql´;
Connection.HostName := ´´;
Connection.Database := ´´;
Connection.User := ´´;
Connection.Password := ´´;
Dataset := TZReadOnlyQuery.Create(nil);
Dataset.Connection := Connection;
Dataset.SQL.Clear;
Dataset.SQL.Add(memo1.Lines.Text);
Dataset.Open; // <==================== NAO SAI DO OPEN ?!
assignfile(arq,´c:\saida.txt´);
rewrite(arq);
while not DataSet.Eof do
begin
linha:= ´´;
for J:= 0 to DataSet.FieldCount-1 do
begin
if not DataSet.DbcResultSet.IsNull(J+1) then
begin
S:= DataSet.DbcResultSet.GetString(J+1);
end;
linha:= linha + s + ´;´;
end;
writeln(arq,linha);
if not DataSet.FindNext then
break;
end;
closefile(arq);
end;
end.Gostei + 0
17/07/2009
Danielrsanches
pq vc não ´parcela´ a exportação dos dados para o arquivo ?
tipo: faça um loop onde vc retorna de 10.000 em 10.000 registros (por exemplo, pode ser mais, dependendo da capacidade da máquina) e vai exportando para o arquivo aos poucos ??? pelo menos vc não precisa usar toda a capacidade da máquina retornando os 6milhões de registros ...
abraços !!!
Gostei + 0
17/07/2009
Maker
já até pensamos nisso, mas eu fiz um teste usando Java e LUA e não tive esse tipo de problema (não se nota aumento na memória). A lógica eh a mesma - executa a query e percorre o resultset. Nossa aplicação para extração é em Delphi, será que vou ter que mudar de linguagem para poder fazer isso?!
Gostei + 0
17/07/2009
Danielrsanches
dependendo do caso, uma troca de linguagem, demanda muito mais tempo e trabalho, do que vc mudar um pouco a lógica e obter o mesmo resultado...
abraços !!!
Gostei + 0
17/07/2009
George_piaulino
Qualquer banco de dados exporta arquivos em formato texto, outros têm até opções de outros tipos de exportações (XML, XlS).
Sendo assim fica mais fácil fazer uma função ou procedure no banco de dados e chamá-la no delphi, aí terá a possibilidade de até criar jobs pelo delphi com threads ou té mesmo nem usar o delphi e sim o próprio job do banco de dados.
Não é aconselhável trazer 6 000 000 registros no client do seu programa, pois por mais que seja, isto irá afetar performance do seu programa e do banco de dados, talvez gerando assim deadlocks.
Esta dica te dou pois enfrentei este mesmo problema anos atrás e resolvi pelo prório banco de dados criando funções e chamando pelo delphi e em alguns casos pelo próprio banco. (aproximadamente gera-se 600 000 registros dia devido a eventos de alarme)
Em todo caso espero ter ajudado.
George :)
Gostei + 0
23/07/2009
Elip2008
DATASET.SQL.CLEAR;
DATASET.SQL.ADD(O_SEU_MEMO);
MAS PARA TER EFEITO, VOCE PRECISA PRIMEIRO FECHAR O DATASET
OUTRA DUVIDA QUE EU FIQUEI FOI VC TAH UTILIZANDO UM TDATASOURCE LIGADO EM TADOQUERY?, SE SIM VC VAI PRECISAR PRIMEIRO FAZER UM TYPECAST, PQ O DATASET NAO SUPORTA A PROPRIEDADE SQL. (NA MINHA DICA VOU COLOCAR UM TDATASOURCE COM O NOME DS E O TDATASOURCE CRIADO LIGADO AO TADOQUERY):
DS.DATASET.CLOSE; //PRECISAMOS GARANTIR QUE O DATASET ESTAJA FECHADA
TADOQYERY(DS.DATASET).SQL.CLEAR;
TADOQUERY(DS.DATASET).SQL.ASSIGN(MEMO1.LINES);
DS.DATASET.OPEN;
Gostei + 0
23/07/2009
Elip2008
Gostei + 0
Clique aqui para fazer login e interagir na Comunidade :)