Re: Funcion SQL mas lenta que un SQL

From: "Omar Zeballos" <ozeballos(at)kantutani(dot)com>
To: "Alvaro Herrera" <alvherre(at)commandprompt(dot)com>
Cc: <pgsql-es-ayuda(at)postgresql(dot)org>
Subject: Re: Funcion SQL mas lenta que un SQL
Date: 2008-03-11 15:19:31
Message-ID: 228c01c8838b$4f70e270$1600a8c0@jefeproyectos
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-es-ayuda

Definitivamente, aún sin hacer las uniones realice la prueba del explain plan y es otro plan de ejecucion el que realiza y es mucho mas lento en el caso de la funcion, si me permiten les envio los resultados, ahora esto se puso mas oscuro para mi, si alguien tiene una explicacion talvez trabajaria mejor al definir estos obejtos en la base.

SELECT doc.codalmacen, kar.codproducto, sum(kar.cantidad)as CANTIDAD
FROM kdx_kardex as kar
INNER JOIN kdx_documentos doc on doc.seqkdxdocumento = kar.seqkdxdocumento
WHERE (doc.coddocumento='RCP' or doc.coddocumento='INV')
AND doc.estado='1'
AND doc.fecha <=$1
AND kar.codproducto = coalesce($2,kar.codproducto)
GROUP BY kar.codproducto, doc.codalmacen

el Analyze con valores fijos me da:

GroupAggregate (cost=2476.27..2476.40 rows=1 width=28) (actual time=4.585..4.586 rows=1 loops=1)"
-> Sort (cost=2476.27..2476.30 rows=12 width=28) (actual time=4.515..4.526 rows=16 loops=1)"
Sort Key: kar.codproducto, doc.codalmacen"
-> Nested Loop (cost=0.00..2476.06 rows=12 width=28) (actual time=0.106..4.456 rows=16 loops=1)"
-> Index Scan using idx_kdxkdx_codpro on kdx_kardex kar (cost=0.00..281.69 rows=301 width=33) (actual time=0.034..0.445 rows=319 loops=1)"
Index Cond: (codproducto = 777::numeric)"
-> Index Scan using idx_seqkdxdoc2 on kdx_documentos doc (cost=0.00..7.28 rows=1 width=19) (actual time=0.011..0.011 rows=0 loops=319)"
Index Cond: (doc.seqkdxdocumento = kar.seqkdxdocumento)"
Filter: ((((coddocumento)::text = 'RCP'::text) OR ((coddocumento)::text = 'INV'::text)) AND ((estado)::text = '1'::text) AND (fecha <= ('now'::text)::date))"
Total runtime: 4.667 ms"

con foo(current_date,100), llamando a una funcion

GroupAggregate (cost=28085.39..28085.77 rows=1 width=28) (actual time=2268.978..2268.979 rows=1 loops=1)"
-> Sort (cost=28085.39..28085.48 rows=36 width=28) (actual time=2268.925..2268.936 rows=16 loops=1)"
Sort Key: kar.codproducto, doc.codalmacen"
-> Merge Join (cost=28059.76..28084.46 rows=36 width=28) (actual time=2259.653..2268.873 rows=16 loops=1)"
Merge Cond: (kar.seqkdxdocumento = doc.seqkdxdocumento)"
-> Sort (cost=24348.80..24355.88 rows=2833 width=33) (actual time=2219.434..2219.655 rows=319 loops=1)"
Sort Key: kar.seqkdxdocumento"
-> Seq Scan on kdx_kardex kar (cost=0.00..24186.35 rows=2833 width=33) (actual time=204.749..2218.792 rows=319 loops=1)"
Filter: (codproducto = COALESCE($2, codproducto))"
-> Sort (cost=3710.96..3716.06 rows=2037 width=19) (actual time=40.176..44.328 rows=6018 loops=1)"
Sort Key: doc.seqkdxdocumento"
-> Bitmap Heap Scan on kdx_documentos doc (cost=67.11..3599.01 rows=2037 width=19) (actual time=2.747..27.325 rows=6018 loops=1)"
Recheck Cond: ((((coddocumento)::text = 'RCP'::text) AND (fecha <= $1) AND ((estado)::text = '1'::text)) OR ((coddocumento)::text = 'INV'::text))"
Filter: (((estado)::text = '1'::text) AND (fecha <= $1))"
-> BitmapOr (cost=67.11..67.11 rows=2037 width=0) (actual time=2.598..2.598 rows=0 loops=1)"
-> Bitmap Index Scan on idx_kdxdoc_coddocfecha (cost=0.00..61.80 rows=2037 width=0) (actual time=2.543..2.543 rows=6018 loops=1)"
Index Cond: (((coddocumento)::text = 'RCP'::text) AND (fecha <= $1) AND ((estado)::text = '1'::text))"
-> Bitmap Index Scan on idx_kdxdoc_coddocnum (cost=0.00..4.29 rows=1 width=0) (actual time=0.052..0.052 rows=0 loops=1)"
Index Cond: ((coddocumento)::text = 'INV'::text)"
Total runtime: 2269.147 ms"

Bueno, estoy trabajando en ver como optimizo esto, no se si debo hacerlo, o no usar funciones SQL, o existe alguna forma de realizar estadisticas sobre funciones para mejorar el plan de analisis o contruir un diccionario de estas funciones en el optimizador.
A la espera de una aclaracion y gracias.
Saludos,
Omar.

> La consulta no es la misma, porque el optimizador se comporta distinto
> en cada caso. En el segundo caso puedes examinar que es lo que piensa
> el optimizador de la siguiente manera:
>
> prepare foo as
> select a,b,c from tabla1 where fecha<=$2 and codproducto=$1
> union all
> select a,b,c from tabla2 where fecha<=$2 and codproducto=$1
> union all
> select a,b,c from tabla3 where fecha<=$2 and codproducto=$1
>
> explain analyze execute foo(100, current_date)
>
> --
> Alvaro Herrera http://www.CommandPrompt.com/
> PostgreSQL Replication, Consulting, Custom Development, 24x7 support
> --
> TIP 6: ¿Has buscado en los archivos de nuestra lista de correo?
> http://archives.postgresql.org/pgsql-es-ayuda
>

In response to

Responses

Browse pgsql-es-ayuda by date

  From Date Subject
Next Message Horacio Degiorgi 2008-03-11 15:30:00 postgresql 8.3 y ubuntu 7.10
Previous Message Alvaro Herrera 2008-03-11 15:18:38 Re: Demora mi consulta