Melhoria na performance com Firebird e Postgresql

Bom dia,
Tenho bases com tabelas acima de 1GB com mais de 11.000.000 de registros e fica super lento mostrar a tela.

O Firebird e o Postgresql trabalham com MVCC.
Isto quer dizer que um SELECT COUNT(*) FROM tbl; fica muito lento para tabelas acima de 1GB.
E como se a Netmake desse prioridade para o mysql e esquecesse de ver como os outros SGDB funcionam.
Vide:
https://wiki.postgresql.org/wiki/Slow_Counting
http://www.firebirdfaq.org/faq5/

Isto implica que se um cliente muito doido, e sempre existe um, quiser fazer um "select * from tbl; " ou uma query trouxer uma quantidade muito grande de registros o scriptcase terá o retorno da query super rápido como no mysql. Mas para montar a paginação irá demorar mais de 18 segundos. Pois o scriptcase usa select count(*) from tbl; para montar a paginação. Consequentemente a grid ou form irá demorar muito para aparecer na tela.

Então como manter o suporte ou mesmo vender uma aplicação que você sabe que será lenta com o passar dos anos e não poderá fazer nada para mudar isto? Pois o framework é fechado. mas há várias maneiras de contornar isto se vocês quiserem.

Nos fontes gerados de uma grid, por exemplo, a função pode ser achado no:
arquivo nome_grid_total.class.php
function quebra_geral()

Exemplo de função quebra_geral gerada pelo scriptcase:

function quebra_geral()
{
global $nada, $nm_lang ;
if ($_SESSION[‘sc_session’][$this->Ini->sc_page][‘grid_xxxxxx_xxxxxx’][‘contr_total_geral’] == “OK”)
{
return;
}
$_SESSION[‘sc_session’][$this->Ini->sc_page][‘grid_xxxxxx_xxxxxx’][‘tot_geral’] = array() ;
$nm_comando = "select count(*) from " . $this->Ini->nm_tabela . " " . $_SESSION[‘sc_session’][$this->Ini->sc_page][‘grid_xxxxx_xxxxxx’][‘where_pesq’];
$_SESSION[‘scriptcase’][‘sc_sql_ult_comando’] = $nm_comando;
$_SESSION[‘scriptcase’][‘sc_sql_ult_conexao’] = ‘’;
if (!$rt = $this->Db->Execute($nm_comando))
{
$this->Erro->mensagem (FILE, LINE, “banco”, $this->Ini->Nm_lang[‘lang_errm_dber’], $this->Db->ErrorMsg());
exit ;
}
$_SESSION[‘sc_session’][$this->Ini->sc_page][‘grid_xxxxx_xxxxx’][‘tot_geral’][0] = “” . $this->Ini->Nm_lang[‘lang_msgs_totl’] . “”;
$_SESSION[‘sc_session’][$this->Ini->sc_page][‘grid_xxxxx_xxxxx’][‘tot_geral’][1] = $rt->fields[0] ;
$rt->Close();
$_SESSION[‘sc_session’][$this->Ini->sc_page][‘grid_xxxxx_xxxxx’][‘contr_total_geral’] = “OK”;
}

Temos o mesmo problema com Oracle.

E se o sistema mesmo tiver sendo usado o MySQL em servidores COMPARTILHADOS, eles ficam mandando relatórios, pedindo
para você melhorar o SCRIPT, acusando que esta sobrecarregando o servidor e justamente
o SQL que esta aparecendo é este: SELECT COUNT(*) FROM tbl heehe

O Primeiro Select count(*) acredito que deva haver para a paginação, mas nas quebras, resumos, não mesmo.

Boa noite,

Discutirei sua sugestão com nossa equipe.

att,
Bernhard Bernsmann

Bernhard,
Obrigado pelo apoio.

Alexandre,

Nós que agradecemos. Assim que eu obtiver algum feedback, deixarei você saber.

att,
Bernhard Bernsmann

Alexandre não manjo nada de Postgre mas não seria o caso de usar uma procedure nesse casos?

Andei lendo hoje sobre essas questão e pelo pouco que consegui captar essa lentidão no postgre se deve a maneira com o postgre controla as transações criando vários copias dos dados de uma mesma tabela em um dado momento garantindo que quem iniciou a leitura de dados em um determinado momento tenha os dados exatamente como estavam naquele momento mesmo que uma transação de escrita tenha sido iniciada concorrentemente.

É isso mesmo ou falei besteira?

Acredito que via procedure o SC trate diferente o retorno, já tentou?

Bom dia,
No mysql fica fácil tirar o select count() com mysql_num_rows.
Mas hoje tenho que ter hombridade para assumir que tirar o select count(
) do firebird e postgresql não é tarefa fácil.
Até porque não há um equivalente do mysql_num_rows.
Acho que para manter a compatibilidade com outros bancos e diminuir código a netmake escolheu o select count(*).
As soluções e correções são meros paleativos e estão em:
http://www.firebirdfaq.org/faq5/
https://wiki.postgresql.org/wiki/Slow_Counting
Peço desculpas pelo meu ar acalorado que esta no post e a netmake.
Saulo creio que sua sugestão não dará certo, mas obrigado por se pronunciar a respeito.

No Cobol, montávamos a impressão em matriz, e contávamos os registros, tanto total como das quebras, isso antes da impressão, durante o loop da busca dos registros. Assim se obtinha o total de registros da quebra antes da impressão, e podíamos fazer contas , médias ponderadas, etc, dentro da matriz.

Contra: Exige mais recurso de memória.

A favor: Menos recurso do banco de dados.

Com o harbour faço o seguinte,

Crio arquivo temporário com os registros válidos através de loop seja por for … next ou do while … enddo para a consulta / relatórios, e utilizo as funções sobre este arquivo temporário.
Antes utilizada vetor, que no harbour não consome memória.

Att,

Jocimar

Bernhard,
Boa tarde,
Alguma novidade?