Jaime Casanova wrote:
On Tue, Sep 2, 2008 at 6:30 PM, Alvaro Herrera <[EMAIL PROTECTED]> wrote:
Alvaro Herrera escribió:

Hasta antes de 8.3, sólo se hacía inlining de funciones muy simples
(creo que ni siquiera podían tener cláusulas FROM).  En 8.3 se introdujo
tecnología un poquito mejor, pero de todas formas la cantidad de
funciones que se pueden mezclar es muy pequeña.
Me equivoqué ... en CVS HEAD (8.4devel) sigue siendo sólo posible hacer
inlining the funciones que son del tipo "SELECT expresión" y nada más.

/*
 * inline_function: try to expand a function call inline
 *

ah! habia visto la funcion pero no me tome la molestia de leer el
comentario... :)

lo que significa que solo es_modalidad_temporal() se estaria
beneficiando del inlining mientras que
es_declaracion_modalidad_temporal() no...
en todo caso, me imagino (Carlos corrigeme si estoy suponiendo
demasiado) que la razon para usar las funciones es que necesitas
chequear lo mismo en varias consultas.
Entonces se me ocurre:
1) Dejar todo en una vista
o
2) Dejar la funcion es_modalidad_temporal() (que posiblemente es
suficientemente simple para el inlining) y convertir la otra en una
vista...


Jaime. En efecto como dices, dejando de llamar la función el SELECT queda asi:

EXPLAIN ANALYZE
SELECT DISTINCT di.declaraciones_importacion_id
FROM
items_declaracion_imp idi,
declaraciones_importacion di,
documentos d,
documentos_do dd
WHERE
idi.declaraciones_importacion_id = di.declaraciones_importacion_id AND
di.documentos_id = d.documentos_id AND
d.documentos_id = dd.documentos_id AND
dd.dos_id = 180000000003039842 AND
es_modalidad_temporal(idi.modalidades_id)

con un muy buen comportamiento asi:

"Unique (cost=162903806.15..162903923.09 rows=1 width=8) (actual time=1276.412..1277.436 rows=2 loops=1)" " -> Nested Loop (cost=162903806.15..162903923.08 rows=1 width=8) (actual time=1276.407..1277.423 rows=2 loops=1)" " -> Merge Join (cost=162903806.15..162903914.78 rows=1 width=24) (actual time=1276.379..1277.375 rows=2 loops=1)" " Merge Cond: (di.declaraciones_importacion_id = idi.declaraciones_importacion_id)" " -> Sort (cost=3503.99..3504.00 rows=4 width=24) (actual time=245.042..245.049 rows=5 loops=1)"
"                    Sort Key: di.declaraciones_importacion_id"
"                    Sort Method:  quicksort  Memory: 17kB"
" -> Hash Join (cost=53.02..3503.95 rows=4 width=24) (actual time=230.303..245.013 rows=5 loops=1)"
"                          Hash Cond: (di.documentos_id = dd.documentos_id)"
" -> Seq Scan on declaraciones_importacion di (cost=0.00..3217.74 rows=62174 width=16) (actual time=0.070..122.260 rows=62174 loops=1)" " -> Hash (cost=52.86..52.86 rows=13 width=8) (actual time=0.251..0.251 rows=25 loops=1)" " -> Bitmap Heap Scan on documentos_do dd (cost=4.40..52.86 rows=13 width=8) (actual time=0.109..0.191 rows=25 loops=1)" " Recheck Cond: (dos_id = 180000000003039842::bigint)" " -> Bitmap Index Scan on h_dos_id3 (cost=0.00..4.40 rows=13 width=0) (actual time=0.091..0.091 rows=25 loops=1)" " Index Cond: (dos_id = 180000000003039842::bigint)" " -> Sort (cost=162900302.16..162900356.46 rows=21719 width=8) (actual time=1022.735..1027.347 rows=3210 loops=1)"
"                    Sort Key: idi.declaraciones_importacion_id"
"                    Sort Method:  quicksort  Memory: 207kB"
" -> Seq Scan on items_declaracion_imp idi (cost=0.00..162898737.67 rows=21719 width=8) (actual time=0.271..1013.179 rows=3645 loops=1)"
"                          Filter: es_modalidad_temporal(modalidades_id)"
" -> Index Scan using pk_documentos on documentos d (cost=0.00..8.29 rows=1 width=8) (actual time=0.012..0.015 rows=1 loops=2)"
"              Index Cond: (d.documentos_id = di.documentos_id)"
"Total runtime: 1277.659 ms"

Gracias. Carlos.

Nota: En efecto las dos funciones son reutilizadas tanto en otros SELECTS de funciones PL como desde scripts. Sin embargo, sabiendo que para aprovechar el inlining, el planeador es así de exigente, vamos a revisar las funciones en PL con más de un select o que a su vez invoquen a otras. También tenemos algunas funciones recursivas muy sencillas con condiciones de escape muy claras y para este caso no hemos tenido inconvenientes (en nuestros casos de negocio tenemos que una o varias declaraciones temporales parten de declaraciones iniciales y a su vez de una temporal se pueden desprender una o mas temporales).
--
TIP 7: no olvides aumentar la configuración del "free space map"

Responder a