Problema com ClientDataSet, datasetprovider

Delphi

29/02/2012

Tenho um sql no IB Expert ele abre normal. Quando jogo no Delphi demora demais para abrir o ClientDataSet. O mesmo código SQL.
Pois se abro o SQLDataSet é muito rápido e com a SqlQuery também muito rápido somente no ClientDataSet que esta muito mais muito mais lento para abrir. Sabe me informar o porquê e se tem algo que daria para melhorar o desempenho do ClientDataSet? Se puder me ajudar agradeço desde já.
Fistsoft-sistemas Empresarial-ltda;

Fistsoft-sistemas Empresarial-ltda;

Curtidas 0

Respostas

Deivison Melo

Deivison Melo

29/02/2012

Seria interessante você liberar os fontes para serem verificados, ou até mesmo disponibilizar o código utilizado!

GOSTEI 0
Gustavo Bretas

Gustavo Bretas

29/02/2012

Atribua um valor (50 por exemplo) na propriedade PacketRecords do ClientDataSet, talvez possa te melhorar!
GOSTEI 0
Guinther Pauli

Guinther Pauli

29/02/2012

Olá

O dbExpress / DataSnap / ClientDataSet trabalha de uma forma diferente de outros engines. Quando você dá um open no CDS, em uma tabela com 1 milhão de registros, todos eles serão carregados para a memória no mesmo instante, em um único fetch, levando horas. De forma diferente, outros engines fazem a carga por demanda, como o BDE, é por esse motivo que as vezes aparece uma ampulheta de SQL enquanto o usuário navega no DBGrid, o engine está trazendo por demanda. O problema disso é que ele consome mais recursos do servidor e menos do client, por prender o curso ativo no SGBDR, ele não sabe quando você vai ou o usuário vai pedir mais registros, então mantém o cursor preso. Não é escalável. Já o dbExpress / DataSnap / ClientDataSet foram projetados para aplicações corporativas, como multicamadas e Web, baseados no conceito de State-Less. Ou seja, dá um único Fetch e liberado tudo no server. Como o Bretas bem comentou, você pode usar Packet Records, mas poderá perder escalabilidade em um ambiente com múltiplos usuários. Outra saída é parametrizar seu SQL.

Att,

Guinther Pauli
https://www.devmedia.com.br/guintherpauli
http://www.twitter.com/guintherpauli
http://facebook.com/guinther.pauli
http://gpauli.com
GOSTEI 0
Fistsoft-sistemas Empresarial-ltda;

Fistsoft-sistemas Empresarial-ltda;

29/02/2012

obrigado meu sql é este
select
P.COD_REP,
R.NOME as NOME_REP,
R.FONE as FONE_REP,
N.NNFE NFE,
P.COD_PED ID_PED,
P.DT_CADASTRO DIGITADO_DIA,
C.RAZAO_SOCIAL NOME_CLIENTE,
C.FONE as FONE_CLI,
C.UF,
C.CIDADE,
P.TOTAL VALOR_PEDIDO,
P.DT_FATURAMENTO FATURADO_DIA,

(select
case when ((sum(IPRAZO.NUM_PGTO) =0 or sum(IPRAZO.NUM_PGTO) is null)) then 0 else
coalesce(cast(sum(IPRAZO.QTDE_DIAS/PRAZO.QTDE_PGTO) as numeric(10,0)),0)
end
from CAD_ITEM_PRAZO IPRAZO
inner join CAD_PED P1 on P1.COD_PED=P.COD_PED
where IPRAZO.CODIGO =PRAZO.COD_PRAZO
and P1.COD_PED=P.COD_PED
and P1.TIPO=P
and P1.EXCLUIDO=NAO

)as PRAZO_MEDIO,

(select
coalesce(cast(sum(P2.TOTAL) as numeric(10,2)),0)
from CAD_PED P2
inner join CAD_CLI C2 on C2.COD_CLI=P2.COD_CLI
inner join CAD_REP R2 on R2.COD_REP=P2.COD_REP
where P2.COD_REP=P.COD_REP
and P2.DT_CADASTRO between 01.01.2011 and 30.01.2012
and P2.TIPO=P
and P2.EXCLUIDO=NAO

seu tirar o sub select abaixo fica rapido porque? tem algo errado?
(select
coalesce(cast(sum(P2.TOTAL) as numeric(10,2)),0)
from CAD_PED P2
inner join CAD_CLI C2 on C2.COD_CLI=P2.COD_CLI
inner join CAD_REP R2 on R2.COD_REP=P2.COD_REP
where P2.COD_REP=P.COD_REP
and P2.DT_CADASTRO between 01.01.2011 and 30.01.2012
and P2.TIPO=P
and P2.EXCLUIDO=NAO
) as TT_PEDIDO_REP
GOSTEI 0
Fistsoft-sistemas Empresarial-ltda;

Fistsoft-sistemas Empresarial-ltda;

29/02/2012

Desculpa galera, errei o sql acima está errado, segue correto abaixo
select
P.COD_REP,
R.NOME as NOME_REP,
R.FONE as FONE_REP,
N.NNFE NFE,
P.COD_PED ID_PED,
P.DT_CADASTRO DIGITADO_DIA,
C.RAZAO_SOCIAL NOME_CLIENTE,
C.FONE as FONE_CLI,
C.UF,
C.CIDADE,
P.TOTAL VALOR_PEDIDO,
P.DT_FATURAMENTO FATURADO_DIA,

(select
case when ((sum(IPRAZO.NUM_PGTO) =0 or sum(IPRAZO.NUM_PGTO) is null)) then 0 else
coalesce(cast(sum(IPRAZO.QTDE_DIAS/PRAZO.QTDE_PGTO) as numeric(10,0)),0)
end
from CAD_ITEM_PRAZO IPRAZO
inner join CAD_PED P1 on P1.COD_PED=P.COD_PED
where IPRAZO.CODIGO =PRAZO.COD_PRAZO
and P1.COD_PED=P.COD_PED
and P1.TIPO=P
and P1.EXCLUIDO=NAO

)as PRAZO_MEDIO,

(select
coalesce(cast(sum(P2.TOTAL) as numeric(10,2)),0)
from CAD_PED P2
inner join CAD_CLI C2 on C2.COD_CLI=P2.COD_CLI
inner join CAD_REP R2 on R2.COD_REP=P2.COD_REP
where P2.COD_REP=P.COD_REP
and P2.DT_CADASTRO between 01.01.2011 and 30.01.2012
and P2.TIPO=P
and P2.EXCLUIDO=NAO
) as TT_PEDIDO_REP

from CAD_PED P
left join CAD_NOTA N on N.COD_PED =P.COD_PED
inner join CAD_CLI C on C.COD_CLI =P.COD_CLI
inner join CAD_REP R on R.COD_REP =P.COD_REP
inner join CAD_PRAZO PRAZO on PRAZO.COD_PRAZO=P.COD_PGTO
where P.DT_CADASTRO between 01.01.2011 and 30.01.2012
and P.TIPO=P
and P.EXCLUIDO=NAO
order by P.COD_REP, P.DT_CADASTRO asc, C.CIDADE, C.RAZAO_SOCIAL

se eu tirar este sql que segue abaixo fica rápido, tem algo errado?
(select
coalesce(cast(sum(P2.TOTAL) as numeric(10,2)),0)
from CAD_PED P2
inner join CAD_CLI C2 on C2.COD_CLI=P2.COD_CLI
inner join CAD_REP R2 on R2.COD_REP=P2.COD_REP
where P2.COD_REP=P.COD_REP
and P2.DT_CADASTRO between 01.01.2011 and 30.01.2012
and P2.TIPO=P
and P2.EXCLUIDO=NAO
) as TT*PE*IDO_REP
GOSTEI 0
Gustavo Bretas

Gustavo Bretas

29/02/2012

Bacana,

Eu vou apontas algumas coisas que eu faria diferente!

1º) No select principal vc faz um relacionamento com a tabela CAD_PRAZO, e só usa ela no sub-select PRAZO_MEDIO, se vc usar o código que esta na tabela CAD_PED (P.COD_PAGTO) no sub-select vai eliminar um relacioanmento no principal, no caso do CASE se NUM_PAGTO igual a zero ou nulo atribui zero, acho que podemos fazer um pouco diferente, altere no seu select para fazer o teste:

cast(calesce((select
sum(IPRAZO.QTDE_DIAS/PRAZO.QTDE_PGTO)
from CAD_ITEM_PRAZO IPRAZO
inner join CAD_PED P1 on P1.COD_PED=P.COD_PED
where IPRAZO.CODIGO = P.COD_PAGTO
and P1.COD_PED=P.COD_PED
and P1.TIPO=P
and P1.EXCLUIDO=NAO
and (IPRAZO.NUM_PGTO <> 0)
and (IPRAZO.NUM_PGTO is not null)
), 0), as numeric(10,0))as PRAZO_MEDIO,

2º) No select que vc diz que esta com o problema de lentidão, eu não vi a nescessidade dos relacionamentos com as tabelas CAD_CLI e CAD_REP, sendo que no where vc só relaciona com o select principal somente o campo P2.COD_REP = P.COD_REP, e soma somente um campo da P2, então tente alterar tbm para o a seguir pra ver se te ajuda:

cast(coalesce((select
sum(P2.TOTAL)
from CAD_PED P2
where P2.COD_REP=P.COD_REP
and P2.DT_CADASTRO between 01.01.2011 and 30.01.2012
and P2.TIPO=P
and P2.EXCLUIDO=NAO
), 0) as numeric(10,2)) as TT_PEDIDO_REP

Mantive os sub-select pq não tenho o banco para testar, mas eu tentaria fazer o select com group by!

Depois nos diga se deu certo!
GOSTEI 0
POSTAR