[firebase-br] ajuda para query

Kleber Caneva kdcc em terra.com.br
Qua Jun 20 09:45:33 -03 2007


Montei a SP com base no Select (Segue abaixo). Para otimizá-la seria 
necessário um conhecimento maior da sua base de dados.

Mas uma coisa eu posso lhe afirmar olhando os Joins:
Você está usando Chaves Multiplas para os relacionamentos. Procure criar um 
Chave Unica para eles. É muito mais rapido o banco comparar 2 numeros 
inteiros do que varias comparações usando AND entre valores de varios tipos. 
isso também faz com que o código seja maior do que precisa ser

[]´s

Kléber Caneva.

CREATE PROCEDURE SP_TESTE
RETURNS (
  CODART INTEGER,
  NOMEART VARCHAR(90),
  TIPO INTEGER,
  SERIE VARCHAR(4),
  NUMERO INTEGER,
  DATA DATE,
  DESCRI VARCHAR(30),
  CLI VARCHAR(16),
  NOME VARCHAR(90),
  ARMAZEM INTEGER,
  IVA NUMERIC(15, 3),
  QUANT INTEGER,
  PMP
)
AS
BEGIN

  /* Saldo Anterior */
  FOR
     SELECT
        ARTIGOS.CODART,
        SUM(( case
               when (tipo_doc.DEBITO_CREDITO='N') then FAC_DET.QUANT
               else (FAC_DET.QUANT*-1) end
           ))
     From ARTIGOS
       INNER JOIN FAC_DET ON (ARTIGOS.CODART = FAC_DET.COD_ART)
       INNER JOIN FACT_CAB ON (FAC_DET.ARMAZEM = FACT_CAB.ARMAZEM) AND 
(FAC_DET.TIPO = FACT_CAB.TIPO_DOC) AND (FAC_DET.SERIE = FACT_CAB.SERIE) AND 
(FAC_DET.NUMERO = FACT_CAB.NUMERO) AND (FAC_DET.DATA = FACT_CAB.DATA_DOC)
       INNER JOIN TIPO_DOC ON (FACT_CAB.ARMAZEM = TIPO_DOC.ARMAZEM) AND 
(FACT_CAB.TIPO_DOC = TIPO_DOC.NUMERO) AND (FACT_CAB.SERIE = TIPO_DOC.SERIE)
     WHERE
       (FAC_DET.ACTZ_STOCK = 'S')
       and (FAC_DET.DATA <= 0 )
       AND ARTIGOS.CODART>='MAZOOTE'
       AND ARTIGOS.CODART<='MAZOOTE'
     INTO :CODART, :QUANT
     GROUP BY ARTIGOS.CODART
  begin
    NOMEART = '    === Saldo Anterior ===';
    TIPO = 1;
    SERIE = '';
    NUMERO = 0;
    DATA = 0;
    DESCRI = '';
    CLI = '';
    NOME = '';
    ARMAZEM = 1;
    IVA = 0;

    SELECT coalesce(avg(FAC_DET.PREC_UNIT),0)
    FROM FAC_DET
    INNER JOIN TIPO_DOC ON (FAC_DET.ARMAZEM = TIPO_DOC.ARMAZEM) AND 
(FAC_DET.TIPO = TIPO_DOC.NUMERO) AND (FAC_DET.SERIE = TIPO_DOC.SERIE)
    WHERE
       (FAC_DET.ACTZ_STOCK = 'S') AND
       (TIPO_DOC.DOC_ENTRADA = 'S') AND
       (FAC_DET.COD_ART = :CODART)
       and (FAC_DET.DATA<=0))
    INTO :PMP ;

    SUSPEND;

  end;


  /* Lançamentos */
  FOR
     SELECT
       ARTIGOS.CODART,
       ARTIGOS.NOMART,
       FAC_DET.TIPO,
       FAC_DET.SERIE,
       FAC_DET.NUMERO,
       FACT_CAB.DATA_DOC,
       FACT_CAB.DESCRI,
       FACT_CAB.CLI,
       FACT_CAB.NOME,
       FACT_CAB.ARMAZEM,
       FAC_DET.IVA,
        SUM(( case
               when (tipo_doc.DEBITO_CREDITO='N') then FAC_DET.QUANT
               else (FAC_DET.QUANT*-1) end
           )),
     From ARTIGOS
       INNER JOIN FAC_DET ON (ARTIGOS.CODART = FAC_DET.COD_ART)
       INNER JOIN FACT_CAB ON (FAC_DET.ARMAZEM = FACT_CAB.ARMAZEM) AND 
(FAC_DET.TIPO = FACT_CAB.TIPO_DOC) AND (FAC_DET.SERIE = FACT_CAB.SERIE) AND 
(FAC_DET.NUMERO = FACT_CAB.NUMERO) AND (FAC_DET.DATA = FACT_CAB.DATA_DOC)
       INNER JOIN TIPO_DOC ON (FACT_CAB.ARMAZEM = TIPO_DOC.ARMAZEM) AND 
(FACT_CAB.TIPO_DOC = TIPO_DOC.NUMERO) AND (FACT_CAB.SERIE = TIPO_DOC.SERIE)
     WHERE
       (FAC_DET.ACTZ_STOCK = 'S')
       and (FAC_DET.DATA <= 0 )
       and (FAC_DET.DATA >= '06-19-2007' )
       AND ARTIGOS.CODART>='MAZOOTE'
       AND ARTIGOS.CODART<='MAZOOTE'
     INTO :CODART, :QUANT
     ORDER BY 1, 2, 3, 4
  begin
    SELECT coalesce(avg(FAC_DET.PREC_UNIT),0)
    FROM FAC_DET
    INNER JOIN TIPO_DOC ON (FAC_DET.ARMAZEM = TIPO_DOC.ARMAZEM) AND 
(FAC_DET.TIPO = TIPO_DOC.NUMERO) AND (FAC_DET.SERIE = TIPO_DOC.SERIE)
    WHERE
       (FAC_DET.ACTZ_STOCK = 'S') AND
       (TIPO_DOC.DOC_ENTRADA = 'S') AND
       (FAC_DET.COD_ART = :CODART)
       and (FAC_DET.DATA<=0))
    INTO :PMP ;

    SUSPEND;

  end;

END;


----- Original Message ----- 
From: "Alberto Brito" <comercial em abritolda.com>
To: <lista em firebase.com.br>
Sent: Tuesday, June 19, 2007 4:43 PM
Subject: Re: [firebase-br] ajuda para query


Talvez então eu esteja efectuando mal a procedure selecionavel
poderiam me dar uma ajuda de como ficaria?

Obrigado


Denis escreveu:
> Nos meus sistemas, eu uso sempre procedures selecionáveis para as 
> instruções
> mais complexas. Funciona muito bem e dentro do sistema fica muito mais
> legivel. Existe tbm um ganho de performance sim. Sem contar que depois a
> manutenção do seu banco de dados fica muito mais fácil.
>
> A solução do Kleber é excelente.
>
> Denis
>
>
> "Kleber Caneva" <kdcc-y7mWNqJcIDpfJ/NunPodnw em public.gmane.org> escreveu na
> mensagem 
> news:104101c7b28e$1c5485f0$8603a8c0-8auliJ6A+oKtq2lpoERdew em public.gmane.org
> Pelo tamanho do Select, já lhe dou o primeiro conselho.. use SP
> Selecionavel..
>
> Além de performace, ficará mais legivel.
>
> []´s
>
> Kléber Caneva
>
> ----- Original Message ----- 
> From: "Alberto Brito" <comercial-82rk/MUwluaB+jHODAdFcQ em public.gmane.org>
> To: <lista-JZX6CTs6PlE39yzSjRtAkw em public.gmane.org>
> Sent: Tuesday, June 19, 2007 12:30 PM
> Subject: [firebase-br] ajuda para query
>
>
> Oi
>
> Venho pedir a ajuda do pessoal, para ver se e possivel optimizar uma 
> query.
>
> tenho a seguinte query:
>
> SELECT
>    ARTIGOS.CODART,
>    CAST('    === Saldo Anterior ===' AS VARCHAR(90))NOMART,
>    CAST('1' AS INTEGER) TIPO,
>    CAST('' AS VARCHAR(4)) SERIE,
>    CAST('0' AS INTEGER) NUMERO,
>    CAST('12-30-1899' AS DATE) DATA,
>    CAST('' AS VARCHAR(30)) DESCRI,
>    CAST('' AS VARCHAR(16)) CLI,
>    CAST('' AS VARCHAR(90)) NOME,
>    CAST('1' AS INTEGER) ARMAZEM,
>    CAST('0' AS NUMERIC(15,3)) IVA,
>    SUM((case when (tipo_doc.DEBITO_CREDITO='N') then FAC_DET.QUANT else
> (FAC_DET.QUANT*-1) end)) AS QUANT,
>    (SELECT coalesce(avg(FAC_DET.PREC_UNIT),0)
> FROM
>    FAC_DET
>    INNER JOIN TIPO_DOC ON (FAC_DET.ARMAZEM = TIPO_DOC.ARMAZEM)
>    AND (FAC_DET.TIPO = TIPO_DOC.NUMERO)
>    AND (FAC_DET.SERIE = TIPO_DOC.SERIE)
> WHERE
>    (FAC_DET.ACTZ_STOCK = 'S') AND
>    (TIPO_DOC.DOC_ENTRADA = 'S') AND
>    (FAC_DET.COD_ART = artigos.codart)
>    and (FAC_DET.DATA<='12-30-1899')) AS PMP
> FROM
>    ARTIGOS
>    INNER JOIN FAC_DET ON (ARTIGOS.CODART = FAC_DET.COD_ART)
>    INNER JOIN FACT_CAB ON (FAC_DET.ARMAZEM = FACT_CAB.ARMAZEM)
>    AND (FAC_DET.TIPO = FACT_CAB.TIPO_DOC)
>    AND (FAC_DET.SERIE = FACT_CAB.SERIE)
>    AND (FAC_DET.NUMERO = FACT_CAB.NUMERO)
>    AND (FAC_DET.DATA = FACT_CAB.DATA_DOC)
>    INNER JOIN TIPO_DOC ON (FACT_CAB.ARMAZEM = TIPO_DOC.ARMAZEM)
>    AND (FACT_CAB.TIPO_DOC = TIPO_DOC.NUMERO)
>    AND (FACT_CAB.SERIE = TIPO_DOC.SERIE)
> WHERE
>    (FAC_DET.ACTZ_STOCK = 'S')
>    and (FAC_DET.DATA <= '12-30-1899' )
>     AND ARTIGOS.CODART>='MAZOOTE'
>     AND ARTIGOS.CODART<='MAZOOTE'
> GROUP BY
>    1,2,3,4,5,6,7,8,9,10,11
> union all
> SELECT
>    ARTIGOS.CODART,
>    ARTIGOS.NOMART,
>    FAC_DET.TIPO,
>    FAC_DET.SERIE,
>    FAC_DET.NUMERO,
>    FACT_CAB.DATA_DOC,
>    FACT_CAB.DESCRI,
>    FACT_CAB.CLI,
>    FACT_CAB.NOME,
>    FACT_CAB.ARMAZEM,
>    FAC_DET.IVA,
>    (case when (tipo_doc.DEBITO_CREDITO='N') then FAC_DET.QUANT else
> (FAC_DET.QUANT*-1) end) as QUANT,
>    (SELECT coalesce(avg(FAC_DET.PREC_UNIT),0)
> FROM
>    FAC_DET
>    INNER JOIN TIPO_DOC ON (FAC_DET.ARMAZEM = TIPO_DOC.ARMAZEM)
>    AND (FAC_DET.TIPO = TIPO_DOC.NUMERO)
>    AND (FAC_DET.SERIE = TIPO_DOC.SERIE)
> WHERE
>    (FAC_DET.ACTZ_STOCK = 'S') AND
>    (TIPO_DOC.DOC_ENTRADA = 'S') AND
>    (FAC_DET.COD_ART = artigos.codart)
>    and (FAC_DET.DATA<=FACT_CAB.DATA_DOC)) AS PMP
> FROM
>    ARTIGOS
>    INNER JOIN FAC_DET ON (ARTIGOS.CODART = FAC_DET.COD_ART)
>    INNER JOIN FACT_CAB ON (FAC_DET.ARMAZEM = FACT_CAB.ARMAZEM)
>    AND (FAC_DET.TIPO = FACT_CAB.TIPO_DOC)
>    AND (FAC_DET.SERIE = FACT_CAB.SERIE)
>    AND (FAC_DET.NUMERO = FACT_CAB.NUMERO)
>    AND (FAC_DET.DATA = FACT_CAB.DATA_DOC)
>    INNER JOIN TIPO_DOC ON (FACT_CAB.ARMAZEM = TIPO_DOC.ARMAZEM)
>    AND (FACT_CAB.TIPO_DOC = TIPO_DOC.NUMERO)
>    AND (FACT_CAB.SERIE = TIPO_DOC.SERIE)
> WHERE
>    (FAC_DET.ACTZ_STOCK = 'S')
>    and (FAC_DET.DATA > '12-30-1899' )
>    and (FAC_DET.DATA <= '06-19-2007' )
>     AND ARTIGOS.CODART>='MAZOOTE'
>     AND ARTIGOS.CODART<='MAZOOTE'
> ORDER BY 1 ASC
>         , 2 ASC
>         , 3 ASC
>         , 4 ASC
>
>
> ela esta a demorar imenso tempo para me retornar os dados
> migrei para o firebird 2.01
> e possivel com os novos recursos optimizar a query para um melhor
> desempenho?
>
>
> Obrigado pessoal
>
> ______________________________________________
> FireBase-BR (www.firebase.com.br) - Hospedado em www.locador.com.br
> Para editar sua configuração na lista, use o endereço
> http://mail.firebase.com.br/mailman/listinfo/lista_firebase.com.br
> Para consultar mensagens antigas: http://firebase.com.br/pesquisa
>
> Esta mensagem foi verificada pelo E-mail Protegido Terra.
> Scan engine: McAfee VirusScan / Atualizado em 18/06/2007 / Versão:
> 5.1.00/5055
> Proteja o seu e-mail Terra: http://mail.terra.com.br/
>
>
>
> ______________________________________________
> FireBase-BR (www.firebase.com.br) - Hospedado em www.locador.com.br
> Para editar sua configuração na lista, use o endereço
> http://mail.firebase.com.br/mailman/listinfo/lista_firebase.com.br
> Para consultar mensagens antigas: http://firebase.com.br/pesquisa
>
>
>
>
>
>
> ------------------------------------------------------------------------
>
> ______________________________________________
> FireBase-BR (www.firebase.com.br) - Hospedado em www.locador.com.br
> Para editar sua configuração na lista, use o endereço 
> http://mail.firebase.com.br/mailman/listinfo/lista_firebase.com.br
> Para consultar mensagens antigas: http://firebase.com.br/pesquisa


______________________________________________
FireBase-BR (www.firebase.com.br) - Hospedado em www.locador.com.br
Para editar sua configuração na lista, use o endereço 
http://mail.firebase.com.br/mailman/listinfo/lista_firebase.com.br
Para consultar mensagens antigas: http://firebase.com.br/pesquisa

Esta mensagem foi verificada pelo E-mail Protegido Terra.
Scan engine: McAfee VirusScan / Atualizado em 19/06/2007 / Versão: 
5.1.00/5056
Proteja o seu e-mail Terra: http://mail.terra.com.br/






Mais detalhes sobre a lista de discussão lista