Jump to content

Nova Loja Oficial
loja.projetoacbr.com.br
Ajude o projeto a crescer, com estilo

Comprar

Balança SM100 performance surpreendente

Tecnologia Japonesa   Teclado e Visor resistentes a água
Consumo inteligente de etiquetas   Baixo custo de manutenção
Comunicação Ethernet e WIFI independentes

Saiba mais

Impressora de Etiquetas ELGIN - L42 PRO

Protocolos PPLA, PPLB, ZPL, EPL (automático)
Porta USB padrão Opcionais: Ethernet, Serial, Paralela
Sensor de Etiquetas Móvel Garantia de 18 meses

Saiba mais

Rodrigo Cardilo

Lentidão para gravar dados Firedac

Recommended Posts

Prezados,

Migrei um sistema multi camadas para o Firedac a algum tempo e percebi uma lentidão para gravar em algumas tabelas com muitos registros.

Minha estrutura é Servidor de Aplicação com Firedac, Cliente Datasnap utilizando ClientDatamodule.

O problema só acontece quando tento gravar uma tabela com mais de 500.000 registros (Tabela de Venda)

Alguém já passou por isso e conseguiu alguma solução?

Grato desde já,


Rodrigo Cardilo

Card System Info

rodrigo@cardilo.com

Share this post


Link to post
Share on other sites

Depende da forma que você faz a gravação. Por exemplo, se estiver carregando dados da tabela ao gravar, isso pode acontecer.


[]'s

Consultor SAC ACBr

Elton
Ajude o Projeto ACBr crescer - Assine o SAC

Projeto ACBr     Telefone:(15) 2105-0750 WhatsApp(15)99790-2976.

Um engenheiro de Controle de Qualidade(QA) entra num bar. Pede uma cerveja. Pede zero cervejas.
Pede 99999999 cervejas. Pede -1 cervejas. Pede um jacaré. Pede asdfdhklçkh.

Share this post


Link to post
Share on other sites
20 minutos atrás, EMBarbosa disse:

Depende da forma que você faz a gravação. Por exemplo, se estiver carregando dados da tabela ao gravar, isso pode acontecer.

DM1.TB10000.PacketRecords := 0;
DM1.TB10000.Open;

Antes de abrir a tabela eu tomo esse cuidado. Utilizo o código acima e depois insiro os dados tanto na tabela mestre (VENDA) como na details (itens). Para gravar, utilizo o código abaixo.

DM1.TB10000.POST;
DM1.TB10000.APPLYUPDATES(-1);

 

 

Interessante que antes no DbExpress funcionava bem mais rápido.

As consultas e gravação em tabelas com menos registros funciona bem, sem problemas.

Edited by Rodrigo Cardilo

Rodrigo Cardilo

Card System Info

rodrigo@cardilo.com

Share this post


Link to post
Share on other sites
22 minutos atrás, Rodrigo Cardilo disse:

Antes de abrir a tabela eu tomo esse cuidado. Utilizo o código acima e depois insiro os dados tanto na tabela mestre (VENDA) como na details (itens). 

Não sei de qual tipo de Dataset é o componente TB10000, mas geralmente PacketRecords não quer dizer quantos registros você vai puxar do BD. Apenas quantos vai puxar por vez.

Então setar ele como 0 não vai necessariamente impedir de puxar todos registros da tabela.

25 minutos atrás, Rodrigo Cardilo disse:

Para gravar, utilizo o código abaixo. 

Bom, no código está apenas o Post e o ApplyUpdates. Qual método do componente você está utilizando para abrir um novo registro? Insert? Append?


[]'s

Consultor SAC ACBr

Elton
Ajude o Projeto ACBr crescer - Assine o SAC

Projeto ACBr     Telefone:(15) 2105-0750 WhatsApp(15)99790-2976.

Um engenheiro de Controle de Qualidade(QA) entra num bar. Pede uma cerveja. Pede zero cervejas.
Pede 99999999 cervejas. Pede -1 cervejas. Pede um jacaré. Pede asdfdhklçkh.

Share this post


Link to post
Share on other sites
12 minutos atrás, EMBarbosa disse:

Não sei de qual tipo de Dataset é o componente TB10000, mas geralmente PacketRecords não quer dizer quantos registros você vai puxar do BD. Apenas quantos vai puxar por vez.

Então setar ele como 0 não vai necessariamente impedir de puxar todos registros da tabela.

Bom, no código está apenas o Post e o ApplyUpdates. Qual método do componente você está utilizando para abrir um novo registro? Insert? Append?

Um resumo da estrutura @EMBarbosa

Servidor: Firedac, AdQuery, Provider

Cliente Datasnap: ClientDataModule(no caso é a TB10000) e datasource

Eu utilizo o Insert mesmo. O packetrecords eu mantenho 0 para não vir registro algum mesmo. 

Fiz um teste com o DBExpress e a performance é bem melhor.


Rodrigo Cardilo

Card System Info

rodrigo@cardilo.com

Share this post


Link to post
Share on other sites
12 minutos atrás, Rodrigo Cardilo disse:

O packetrecords eu mantenho 0 para não vir registro algum mesmo.

E você tem certeza que não está vindo nenhum registro? Em caso afirmativo, eu sugiro você utilizar algum profiler.

É melhor você medir exatamente onde está a demora que a gente ficar especulando.

Talvez queira tentar o dbgSpider, ou o asmprofiler, ou ainda o Sampling Profiler.


[]'s

Consultor SAC ACBr

Elton
Ajude o Projeto ACBr crescer - Assine o SAC

Projeto ACBr     Telefone:(15) 2105-0750 WhatsApp(15)99790-2976.

Um engenheiro de Controle de Qualidade(QA) entra num bar. Pede uma cerveja. Pede zero cervejas.
Pede 99999999 cervejas. Pede -1 cervejas. Pede um jacaré. Pede asdfdhklçkh.

Share this post


Link to post
Share on other sites
21 horas atrás, EMBarbosa disse:

E você tem certeza que não está vindo nenhum registro? Em caso afirmativo, eu sugiro você utilizar algum profiler.

É melhor você medir exatamente onde está a demora que a gente ficar especulando.

Talvez queira tentar o dbgSpider, ou o asmprofiler, ou ainda o Sampling Profiler.

@EMBarbosaInfelizmente não sei usar nenhum dos profiles.

Mas utilizando o POG (Programação orientado a gambiarra) eu achei o momento da lentidão. Está exatamente no ApplyUpdates.

Daí concluí que é realmente não hora de gravar. E tenho certeza que não está vindo nenhum registro pois a tabela abre rapidamente (atualizando que a quantidade de registros da tabela Mestre (Venda) é de 1.600.000 aproximadamente. 

Estou pensando em abandonar o Firedac


Rodrigo Cardilo

Card System Info

rodrigo@cardilo.com

Share this post


Link to post
Share on other sites
8 minutos atrás, Rodrigo Cardilo disse:

Infelizmente não sei usar nenhum dos profiles.

Rapaz, usar os profilers é muito simples. Dá uma chance pra eles. :)

É o tipo de ferramenta que depois de aprender a utilizar te abre uma nova visão das coisas.

6 minutos atrás, Rodrigo Cardilo disse:

Mas utilizando o POG (Programação orientado a gambiarra) eu achei o momento da lentidão. Está exatamente no ApplyUpdates. 

Daí concluí que é realmente não hora de gravar. E tenho certeza que não está vindo nenhum registro pois a tabela abre rapidamente (atualizando que a quantidade de registros da tabela Mestre (Venda) é de 1.600.000 aproximadamente.  

Mesmo uma tabela desse tamanho, se você está apenas inserindo um novo registro, o tempo gasto deveria ser bem pequeno. Você pode verificar isso executando o SQL diretamente.

10 minutos atrás, Rodrigo Cardilo disse:

Estou pensando em abandonar o Firedac 

A menos que você esteja pensando em adotar um ORM como o mORMot, sugiro você tentar descobrir o problema e resolver.


[]'s

Consultor SAC ACBr

Elton
Ajude o Projeto ACBr crescer - Assine o SAC

Projeto ACBr     Telefone:(15) 2105-0750 WhatsApp(15)99790-2976.

Um engenheiro de Controle de Qualidade(QA) entra num bar. Pede uma cerveja. Pede zero cervejas.
Pede 99999999 cervejas. Pede -1 cervejas. Pede um jacaré. Pede asdfdhklçkh.

Share this post


Link to post
Share on other sites
10 horas atrás, EMBarbosa disse:

Rapaz, usar os profilers é muito simples. Dá uma chance pra eles. :)

É o tipo de ferramenta que depois de aprender a utilizar te abre uma nova visão das coisas.

@EMBarbosa eu tentei usar.. Mas não mostrou nenhuma novidade. Confesso que não sei usar a ferramenta direito mas, como te disse antes, é no applyupdates que a coisa trava.

10 horas atrás, EMBarbosa disse:

Mesmo uma tabela desse tamanho, se você está apenas inserindo um novo registro, o tempo gasto deveria ser bem pequeno. Você pode verificar isso executando o SQL diretamente

Eu já fiz um teste com o sql direto (INSERT INTO......) e aí funciona bem mais rápido. Mas aí vou ter que abandonar o clientdataset e é quase impossível modificar essa estrutura toda.

 

10 horas atrás, EMBarbosa disse:

menos que você esteja pensando em adotar um ORM como o mORMot, sugiro você tentar descobrir o problema e resolver.

Estou pensando em voltar pro DbExpress ou Unidac, segundo relatos de outros que tiveram problema parecido. Lembrando que minha aplicação cliente utiliza DATASNAP. Gostei muito do Firedac mas com essa lentidão tá complicado.


Rodrigo Cardilo

Card System Info

rodrigo@cardilo.com

Share this post


Link to post
Share on other sites
10 horas atrás, Rodrigo Cardilo disse:

Confesso que não sei usar a ferramenta direito mas, como te disse antes, é no applyupdates que a coisa trava. 

Ser no applyUpdates não quer dizer nada. Esse método faz tanta coisa, que você não sabe o motivo real da lentidão. Por isso um profiler é a melhor ferramenta...

Só insisti nisso porque você está indo na contramão de todos os benchmarks que vi sobre o assunto. O FireDAC desbanca o dbExpress em muito.

10 horas atrás, Rodrigo Cardilo disse:

Eu já fiz um teste com o sql direto (INSERT INTO......) e aí funciona bem mais rápido. Mas aí vou ter que abandonar o clientdataset e é quase impossível modificar essa estrutura toda.

A ideia de fazer o sql era apenas para saber sobre a velocidade mesmo. Afinal se com o SQL puro não ficasse mais rápido, o problema era o BD.

Agora, se você está utilizando TClientDataset então tem outras coisas envolvidas. A dinâmica é muito diferente. Tem coisas que o TClientDataSet só faz no ApplyUpdates.

10 horas atrás, Rodrigo Cardilo disse:

Estou pensando em voltar pro DbExpress ou Unidac, segundo relatos de outros que tiveram problema parecido. Lembrando que minha aplicação cliente utiliza DATASNAP. Gostei muito do Firedac mas com essa lentidão tá complicado

Bom, não tem sentido eu ficar insistindo em algo que você não quer fazer. Mesmo porque não sou eu quem tem que lidar com os problemas.

Só falei o que é minha opinião particular, de uma pessoa que já lidou com vários problemas de lentidão assim.

Por outro lado seria falso da minha parte não lembrar que DBexpress é considerada tecnologia obsoleta


[]'s

Consultor SAC ACBr

Elton
Ajude o Projeto ACBr crescer - Assine o SAC

Projeto ACBr     Telefone:(15) 2105-0750 WhatsApp(15)99790-2976.

Um engenheiro de Controle de Qualidade(QA) entra num bar. Pede uma cerveja. Pede zero cervejas.
Pede 99999999 cervejas. Pede -1 cervejas. Pede um jacaré. Pede asdfdhklçkh.

Share this post


Link to post
Share on other sites
2 horas atrás, EMBarbosa disse:

Ser no applyUpdates não quer dizer nada. Esse método faz tanta coisa, que você não sabe o motivo real da lentidão. Por isso um profiler é a melhor ferramenta...

Só insisti nisso porque você está indo na contramão de todos os benchmarks que vi sobre o assunto. O FireDAC desbanca o dbExpress em muito.

@EMBarbosa concordo plenamente com você. Quanto tentei usar o profiler confesso que não entendi muito o funcionamento. E só mostrou resultados para a ntdll. Não achei nada sobre o assunto no google e por isso não insisti. Fiz vários testes. Por exemplo: Numa tabela com 500 registros não tenho problema algum de lentidão. Quando faço uma consulta o retorno dos registros também é muito mais rápido que no obsoleto DBExpress. Porém, na principal tabela do meu sistema que é a de vendas e onde eu preciso de maior agilidade está acontecendo isso. Tenho uma outra tabela com 500000 registros que também acontece o mesmo problema. Outro teste que fiz foi uma conexão direta, sem Datasnap. As coisas mudam. A gravação é bem mais rápida. Por isso postei ajuda aqui pois não sei se muda alguma coisa no Datasnap. Comecei a testar outras alternativas aqui e se puderem me dar sugestões eu agradeço desde já.


Rodrigo Cardilo

Card System Info

rodrigo@cardilo.com

Share this post


Link to post
Share on other sites
2 horas atrás, Rodrigo Cardilo disse:

Porém, na principal tabela do meu sistema que é a de vendas e onde eu preciso de maior agilidade está acontecendo isso. Tenho uma outra tabela com 500000 registros que também acontece o mesmo problema. Outro teste que fiz foi uma conexão direta, sem Datasnap. As coisas mudam. A gravação é bem mais rápida. Por isso postei ajuda aqui pois não sei se muda alguma coisa no Datasnap. Comecei a testar outras alternativas aqui e se puderem me dar sugestões eu agradeço desde já. 

Minha ideia é você verificar o que está acontecendo. Se a lentidão está acontecendo com tabelas maiores, mas ela não acontece via SQL, então a explicação mais plausível é que o componente está carregando registros da tabela.

Tive um problema desses uma vez com o TClientDataset. Como ele estava ligado a um IBDataSet onde colocávamos o SQL, só pra testar eu alterei o select do SQL incluindo um limite de linhas.

Por exemplo:

SELECT
  NOME
FROM CLIENTES
ROWS 1 TO 50

A lentidão foi embora. A partir daí eu fui verificar o que o componente estava fazendo pra abrir e consegui resolver.


[]'s

Consultor SAC ACBr

Elton
Ajude o Projeto ACBr crescer - Assine o SAC

Projeto ACBr     Telefone:(15) 2105-0750 WhatsApp(15)99790-2976.

Um engenheiro de Controle de Qualidade(QA) entra num bar. Pede uma cerveja. Pede zero cervejas.
Pede 99999999 cervejas. Pede -1 cervejas. Pede um jacaré. Pede asdfdhklçkh.

Share this post


Link to post
Share on other sites
Em 29/03/2019 at 14:31, EMBarbosa disse:

Minha ideia é você verificar o que está acontecendo. Se a lentidão está acontecendo com tabelas maiores, mas ela não acontece via SQL, então a explicação mais plausível é que o componente está carregando registros da tabela.

Tive um problema desses uma vez com o TClientDataset. Como ele estava ligado a um IBDataSet onde colocávamos o SQL, só pra testar eu alterei o select do SQL incluindo um limite de linhas.

Por exemplo:


SELECT
  NOME
FROM CLIENTES
ROWS 1 TO 50

A lentidão foi embora. A partir daí eu fui verificar o que o componente estava fazendo pra abrir e consegui resolver.

@EMBarbosa perfeito. acrescentei row 1 to 50 e ficou infinitamente mais rápido. Já implementei e o usuário está feliz.. (rs) Mas confesso que não entendo o porque dessa demora. Você sugere alguma mudança no componente?

Te agradeço muito pela solução desde já.

Você deixou muita gente feliz nesse começo de semana (kkk). 

  • Like 1

Rodrigo Cardilo

Card System Info

rodrigo@cardilo.com

Share this post


Link to post
Share on other sites
47 minutos atrás, Rodrigo Cardilo disse:

Você sugere alguma mudança no componente?

Te agradeço muito pela solução desde já.

Você deixou muita gente feliz nesse começo de semana (kkk). 

Fico feliz de ter ajudado.

Mas é como eu tinha dito antes: O problema é que há registros que estão sendo carregados na hora da inserção.

Eu teria que ver o código novamente pra poder te dar mais detalhes, mas na minha cabeça é mais ou menos assim que está:

  1. Você faz o Insert e preenche o registro no TClientDataset;
  2. O TClientDataset faz as validações de acordo com os TFields e por isso não precisa de acessar o BD;
  3. Quando você faz um post, o TClientDataset confirma os dados, mas ainda não manda pro BD;
  4. Na hora que você faz um ApplyUpdates, o "cds" vai enviar os dados pro BD;
  5. ele executa um open no componente que é a fonte dos dados;
  6. Ele converte o registro para o formato que é a fonte dos dados (por exemplo um "insert em formato SQL");
  7. Daí executa o insert e faz o commit;

Esse passo 5 acima é onde acontece a lentidão. Porque ao abrir a fonte de dados ele carrega muitos registros.

Mas aí você vai dizer: "Mas e o packedRecords?"

E a resposta é que PackedRecords não é quantidade de registros. É quantidade de registros no pacote. Isso quer dizer que quando você diminui você pode até mesmo tornar a situação ainda mais lenta. É como um pacote que você usa no mercado. Se ele couber poucos volumes, você vai precisar fazer mais viagens.

É mais ou menos isso...

  • Like 1

[]'s

Consultor SAC ACBr

Elton
Ajude o Projeto ACBr crescer - Assine o SAC

Projeto ACBr     Telefone:(15) 2105-0750 WhatsApp(15)99790-2976.

Um engenheiro de Controle de Qualidade(QA) entra num bar. Pede uma cerveja. Pede zero cervejas.
Pede 99999999 cervejas. Pede -1 cervejas. Pede um jacaré. Pede asdfdhklçkh.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×
×
  • Create New...