GARANTIR DESCONTO

Fórum ZeosLib SQL Server 6 milhoes de reg #372221

14/07/2009

0

Tenho uma tabela no SQL Server que possui 6 milhoes de registros. Qdo executo a query (comando open) o programa nao sai do open, ele fica consumindo e consumindo memoria como se estivesse alocando td de uma vez.

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

Maker

Responder

Posts

14/07/2009

Lightshine

Vc faz algum filtro antes de dar o open na tabela??

É 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


Responder

Gostei + 0

14/07/2009

Maker

Nao quero usar filtro. Quero extrair todos os registros. Se tivesse q usar filtro e o retorno viesse nessa msm base de milhoes daria o msm problema. A solucao nao eh essa.

Estou chegando a conclusao que eh uma limitacao dessas 2 bibliotecas (ADO e ZeosLib).


Responder

Gostei + 0

14/07/2009

Woinch

Não sei se existe alguma máquina que suporte mostrar esses 6 milhões de registros! Experimente dar um select * no próprio gerenciador do banco de dados por exemplo. Agora se você não quiser fazer filtro como o nosso colega mencionou, será que a propriedade PacketRecords do ClientDataSet não seria útil? Dê uma pesquisada nela.

Espero ter ajudado.


Responder

Gostei + 0

14/07/2009

Osocram

Qual seria o motivo de trazer todos esses registros de uma so vez?

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.
Nao quero usar filtro. Quero extrair todos os registros. Se tivesse q usar filtro e o retorno viesse nessa msm base de milhoes daria o msm problema. A solucao nao eh essa. Estou chegando a conclusao que eh uma limitacao dessas 2 bibliotecas (ADO e ZeosLib).



Responder

Gostei + 0

16/07/2009

Maker

Obrigado pelas respostas. Mas eu nao estou jogando ele na memoria, estou jogando para um arquivo. Não quero exibir registro algum na tela. Estou querendo extrair os registros para um arquivo. Fazer filtro não eh a solução, repito.

Vou dar uma olhada sobre essa propriedade PacketRecords.


Alguem mais tem alguma idéia?


Responder

Gostei + 0

16/07/2009

Lightshine

Obrigado pelas respostas. Mas eu nao estou jogando ele na memoria, estou jogando para um arquivo. Não quero exibir registro algum na tela. Estou querendo extrair os registros para um arquivo. Fazer filtro não eh a solução, repito. Vou dar uma olhada sobre essa propriedade PacketRecords. Alguem mais tem alguma idéia?


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


Responder

Gostei + 0

17/07/2009

Maker

Olá Lightshine,

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.

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.



Responder

Gostei + 0

17/07/2009

Maker

Nao tem botao de edit no post ???!!
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.



Responder

Gostei + 0

17/07/2009

Danielrsanches

só 1 dica:

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 !!!


Responder

Gostei + 0

17/07/2009

Maker

Olá daniel,

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?!


Responder

Gostei + 0

17/07/2009

Danielrsanches

olha !!! isso já depende de um estudo aí de vcs ... se da forma que dei idéia não for realmente viável fazer, sendo mais viável a troca de linguagem ou de componente, terá que trocar ...

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 !!!


Responder

Gostei + 0

17/07/2009

George_piaulino

O que indico é muito simples.

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 :)


Responder

Gostei + 0

23/07/2009

Elip2008

PELO QUE EU VI VC TAH ADICIONANDO UM COMANDO
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;


Responder

Gostei + 0

23/07/2009

Elip2008

PELO QUE EU VI VC TAH ADICIONANDO UM COMANDO 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 TADOQUERY(DS.DATASET).SQL.CLEAR; TADOQUERY(DS.DATASET).DISABLECONTROLS; TADOQUERY(DS.DATASET).SQL.ASSIGN(MEMO1.LINES); DS.DATASET.OPEN; TADOQUERY(DS.DATASET).SQL.ENABLECONTROLS; DESABILITANDO OS CONTROLES E HABILITANDO DEPOIS A PROCURA FICA UM POUCO MAIS RAPIDO. DESCULPA PELO O POST ANTERIOR, SOH VI DEPOIS Q O DATASET EH A PROPRIA QUERY E ESTAH SENDO CRIADA AUTOMATICAMENTE, DE QUALQUER FORMA FICA A DICA. ENTAUM TROCANDO O CODIGO, FICA ASSIM: DATASET.CLOSE; DATASET.SQL.CLEAR; DATASET.DISABLECONTROLS; DATASET.SQL.ASSIGN(MEMO1.LINES); DATASET.OPEN; DATASET.ENABLECONTROLS;



Responder

Gostei + 0

Utilizamos cookies para fornecer uma melhor experiência para nossos usuários, consulte nossa política de privacidade.

Aceitar