Rodrigo,

Após uma verificação *muito* superficial, segue meu pitaco ...


O problema não parece estar na query, mas no numero de queries 
necessário para calcular devolvidos.

Vamos supor que em sua primeira tabela, vc tenha algo em torno de 100 
registros...
Serão executadas 100 vezes a query da função devolvidos, aparentemente 
com sequencial scan;
Isto sem considerar os joins ...
Sugiro que em vez de utilizar uma função vc utilize um join com os 
registros devolvidos ...




Sds,
Marco Antonio


..:: Rodrigo Machado ::.. wrote:
> Boa tarde amigos, tenho uma consulta que faz referencia a duas tabelas,
> uma onde tem os dados que realmente quero consultar, e outra onde 
> testo se ouve uma devolucao de tal produto... se ouve, ele resta da 
> coluna quantidade quandos foram devolvidos.
>
> o problema está que eu recem estou aprendendo, e esta consulta em 
> alguns clientes com um volumem de dados consideravel, esta demorando 
> muito...
>
> algum amigo poderia me dar uma mao?
> segue o explain da consulta.. e mais a baixo a consulta propiamente.
>
> Nested Loop  (cost=1828.15..1841.35 rows=330 width=319)
>   ->  Sort  (cost=836.84..837.67 rows=330 width=102)
>         Sort Key: public.movis.c_cpd
>         ->  HashAggregate  (cost=759.51..823.04 rows=330 width=102)
>               ->  Index Scan using ind_emismovis on movis  
> (cost=0.00..619.35 rows=3298 width=102)
>                     Index Cond: ((d_emis >= '2007-08-01'::date) AND 
> (d_emis <= '2007-08-21'::date))
>                     Filter: ((c_tipo = 'V'::bpchar) AND ((n_cant - 
> devolvidos(c_cpd, c_nota)) > 0::numeric))
>   ->  Materialize  (cost=991.31..991.32 rows=1 width=32)
>         ->  Aggregate  (cost= 991.27..991.30 rows=1 width=48)
>               ->  Seq Scan on movis  (cost=0.00..960.36 rows=6181 
> width=48)
>                     Filter: (((d_emis)::text >= '20070801'::text) AND 
> (d_emis <= '2007-08-21'::date) AND (c_tipo = 'V'::bpchar))
>
>
>
> SELECT lucrorentabilidad.c_cpd, lucrorentabilidad.c_descr, 
> lucrorentabilidad.cant, lucrorentabilidad.costounit, 
> lucrorentabilidad.ventaunit, lucrorentabilidad.totcosto, 
> lucrorentabilidad.totventa, lucrorentabilidad.totganancia , 
> lucrorentabilidad.ganancia, lucrorentabilidad.rentabilidad    
> FROM ( SELECT salidas.c_cpd, salidas.c_descr, salidas.cant, 
> salidas.costounit, salidas.ventaunit, salidas.totcosto, 
> salidas.totventa, salidas.totganancia , salidas.ganancia, 
> round(salidas.totganancia / totganancia.totganancia * 100, 3) AS 
> rentabilidad            
>         FROM ( SELECT movis.c_cpd, movis.c_descr, 
> sum(movis.n_cant-devolvidos(c_cpd,c_nota)) AS cant, round(sum( 
> movis.n_costogs*(n_cant-devolvidos(c_cpd,c_nota))) / 
> sum(movis.n_cant-devolvidos(c_cpd,c_nota)),2) AS costounit, 
> round(sum(movis.n_costogs*(n_cant-devolvidos(c_cpd,c_nota))) / 
> sum(movis.n_cant-devolvidos(c_cpd,c_nota)),2) AS ventaunit, round(sum( 
> movis.n_costogs*(n_cant-devolvidos(c_cpd,c_nota))),2) AS totcosto, 
> round(sum(movis.n_costogs*(n_cant-devolvidos(c_cpd,c_nota))),2) AS 
> totventa, 
> round(sum(movis.n_costogs*(n_cant-devolvidos(c_cpd,c_nota))),2) - 
> round(sum(movis.n_costogs* (n_cant-devolvidos(c_cpd,c_nota) )),2) AS 
> totganancia, 
> round((round(sum(movis.n_costogs*(n_cant-devolvidos(c_cpd,c_nota))) / 
> sum(movis.n_cant-devolvidos(c_cpd,c_nota)),2) - 
> round(sum(movis.n_costogs*(n_cant-devolvidos(c_cpd,c_nota))) / sum( 
> movis.n_cant-devolvidos(c_cpd,c_nota)),2)) / 
> round(sum(movis.n_costogs*(n_cant-devolvidos(c_cpd,c_nota))) / 
> sum(movis.n_cant-devolvidos(c_cpd,c_nota)),2) * 100,2) AS 
> ganancia                    
>                     FROM movis                   
>                     WHERE movis.d_emis >= '20070801' and 
> movis.d_emis<='20070821' and c_tipo='V' and 
> movis.n_cant-devolvidos(c_cpd,c_nota)>0  
>                     GROUP BY movis.c_cpd , 
> movis.c_descr                   
>                     ORDER BY movis.c_cpd) salidas       JOIN ( SELECT 
> sum(movis.n_costogs*(n_cant-devolvidos(c_cpd,c_nota))) - 
> sum(movis.n_costogs*(n_cant-devolvidos(c_cpd,c_nota))) AS 
> totganancia                    
>                                                                        
>        FROM movis                   
>                                                                        
>        WHERE movis.d_emis >= 20070801 and movis.d_emis<='20070821' AND 
> c_tipo='V') totganancia ON TRUE) lucrorentabilidad
>                                                                        
>        ORDER BY lucrorentabilidad.c_cpd;
>
>
>
> Obs: a funcao DEVOLVIDOS() me retorna um numero negativo caso ouve 
> devolucao, do contrario, me retorna 0.
>
> CREATE OR REPLACE FUNCTION devolvidos(bpchar, bpchar)
>   RETURNS "numeric" AS
> $BODY$                             select sum(n_cant) from (         
>                         select sum(n_cant) as n_cant from movie     
>                             where c_nota=$2 and c_tipo='D' and 
> c_cpd=$1                             union                             
> select 0 as n_cant                             ) as movie;             
>             $BODY$
>   LANGUAGE 'sql' VOLATILE;
> ALTER FUNCTION devolvidos(bpchar, bpchar) OWNER TO postgres;
> ------------------------------------------------------------------------
>
> _______________________________________________
> pgbr-geral mailing list
> [email protected]
> https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral
>   


-- 
Marco Antonio P D'Andrade
Gerência Técnica de Segurança de Suporte Servidores IP - ELN120024
Embratel - Rio de Janeiro - RIT 521-4898 

_______________________________________________
pgbr-geral mailing list
[email protected]
https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral

Responder a