Consulta Demorada

Bom Dia,

Tenho uma query que roda no banco Firebird em 16 milissegundos. Criei uma aplicação do tipo consulta é a mesma inicia com um filtro igual à do where da consulta mais demora mais de 4 minutos para exibir o resultado. Já criei uma VIEW mas o tempo ficou os mesmo 4 minutos.

Alguém teria alguma ideia do que pode ser essa demora?

Cola o SELECT da consulta aqui sem usar o VIEW, o SC demora porque ele faz count(*) na tabela toda vez antes de iniciar a consulta no MySQL isso é rápido mais em outros bancos é um CAOS, ai tem um macete para enganar isso.

Esse problema do count(*) já foi comentado até em outro POST:
http://www.scriptcase.com.br/forum/index.php?topic=9068.0

O select :

SELECT
O.LOJA,
O.OPERADOR,
P.CODAPLICACAO,
SGE.cota AS COTA,
EXTRACT(YEAR FROM DATASTATUS) AS ANO,
EXTRACT(MONTH FROM DATASTATUS) AS MES,
SUM(IP.PRECOIP.QUANTIDADE
(SELECT COALESCE(SUM(R.VALORBRUTO),0)
FROM RECEBIMENTOS R
WHERE R.LOJA = O.LOJA
AND R.CODORCAMENTO = O.CODORCAMENTO
AND R.STATUS = 1)/O.TOTALPRODUTOS) AS BRUTO,

 SUM(IP.PRECO*IP.QUANTIDADE*
   (SELECT COALESCE(SUM(R.VALORBRUTO),0) FROM RECEBIMENTOS R WHERE R.LOJA = O.LOJA AND       R.CODORCAMENTO = O.CODORCAMENTO
   AND R.TIPO NOT IN (11,400,1200)
AND R.STATUS = 1)/O.TOTALPRODUTOS) AS LIQUIDO,

SUM(IP.PRECO*IP.QUANTIDADE*
 (SELECT COALESCE(SUM(R.VALORBRUTO),0) 
  FROM RECEBIMENTOS R 
WHERE R.LOJA = O.LOJA 
AND R.CODORCAMENTO = O.CODORCAMENTO 
AND R.STATUS = 1
AND R.TIPO IN (11,400,1200))/O.TOTALPRODUTOS) AS VALES,
COALESCE(SUM(IP.QUANTIDADE * IP.PRECOCUSTO),0) AS CMV

FROM ORCAMENTOS O
JOIN ITEMSPROD IP ON (O.LOJA = IP.LOJA AND O.CODORCAMENTO = IP.CODORCAMENTO)
JOIN PRODUTOS P ON (P.CODPRODUTO = IP.CODPRODUTO)
left JOIN sge_cota_vendedor SGE ON (SGE.loja = O.loja AND
SGE.operador = O.operador AND
SGE.CODAPLICACAO = P.codaplicacao AND
SGE.ano = EXTRACT(YEAR FROM O.DATASTATUS) AND
SGE.MES = EXTRACT(MONTH FROM O.DATASTATUS))
WHERE
O.STATUS = 1 and
P.codaplicacao IN (1,2) and
O.operador <> ‘S/COMISSAO’
GROUP BY 01,02,03,04,05,06

  1. vc faz subselect nas colunas, tente criar uma view.
    ou
  2. tente colocar os subselects como tabelas no from.
    ou
  3. crie uma tabela temporaria, alimente-a no evento onscriptinit e faça a consulta em cima dessa tabela.

Além destas dicas do Haroldo, no WHERE do SQL ou VIEW adicione isso:

O.CODORCAMENTO <[glo_FILTRO]

Em aplicações > Variáveis Globais [glo_FILTRO] << Marque como Saída.

Cole isso no Evento onApplicationInit:
[glo_FILTRO]=0;

No Filtro > Avançado > Evento OnValidate coloque:
[glo_FILTRO]=99999999;

Testar, para ver se melhorou o carregamento…

Irei fazer esse teste é em seguida eu passo uma resposta.

Haroldo,

Só mais uma dúvida, quando você falou 3) crie uma tabela temporaria, alimente-a no evento onscriptinit e faça a consulta em cima dessa tabela. como seria esse processo de criação? procurei no Forum é não encontrei.

crie uma tabela do tipo engine=myisam com os campos que deseja que saiam na coluna, crie duas colunas para guardar a sessão do php e a data (defatul CURRENT_TIMESTAMP()) da geração

no evento onscriptinit ou no evento onvalidate do filtro (caso inicie sempre pelo filtro a consulta).

exclua todos os registros com data <= a ontem.

faça insert na tabela temporária baseado no seu select complexo, alimente a coluna da sessão do php, o campo data o próprio banco alimenta automaticamente

instrua o select da consulta a exibir somente os registros que sejam da sessão corrente.

  • Eu costumo usar Stored Procedure para alimentar a tabela temporária.

O Banco dele é Firebird Haroldo

ops.

só adaptar.

é justamente por isso o problema dele, por ser firebird o motor.

Firebir assim como postgres não se da nada bem com SELECT COUNT(*)

mas não usa select count(*)

O que o Willian falou é verdade.
Para criar tabelas temporárias no Firebird use a sintaxe para "Global Temporary Tables (GTTs) ":
Do manual http://firebirdsql.org/refdocs/langrefupd25-ddl-table.html

“CREATE GLOBAL TEMPORARY TABLE name
(column_def [, column_def | table_constraint …])
[ON COMMIT {DELETE | PRESERVE} ROWS]”

E depois

insert into minhaGTT (column_def , column_def…) seu select
Exemplo: insert into minhaGTT (campo1, campo2, campo3) select campo1, campo2, campo3 from outra tabela;

Pode usar uma store procedure para rodar o insert ou … Deixo com você.

GTTs são mantidas em memória por isto seu aceso é mais rápido.
Mas não jogue muitos dados nela ou ficará na mesma situação -> http://www.firebirdfaq.org/faq5/ -> Select count(*) is slow

Haroldo para fazer a paginação o Scriptcase usa select count(*) o que deixa banco Firebird e Postgresql uma carroça.
http://www.scriptcase.com.br/forum/index.php/topic,5689.msg34780.html#msg34780

si fizer tudo manual não, mas no caso dele que estava usando nativo filtro do SC , o SC faz.

ah sim, por isso demos sugestões alternativas para melhorar performance dessa consulta que ele reclamou.