Re: Cómo cambio el plan de ejecución de un query

From: "Carlos Beltrán V(dot)" <cbeltran(at)roldan(dot)net>
To: Jaime Casanova <jcasanov(at)systemguards(dot)com(dot)ec>
Cc: ListaPostgreSQL <pgsql-es-ayuda(at)postgresql(dot)org>
Subject: Re: Cómo cambio el plan de ejecución de un query
Date: 2008-08-28 19:13:20
Message-ID: 48B6F8D0.1020008@roldan.net
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-es-ayuda

Jaime Casanova wrote:
> On 8/28/08, "Carlos Beltrán V." <cbeltran(at)roldan(dot)net> wrote:
>
>> El planeador no ejecuta primero el filtro correspondiente al SELECT interno,
>> y por lo tanto la complejidad del SELECT total sube por número de líneas al
>> count() de la tabla más compleja que es la primera que aparece en el SELECT
>> interno.
>>
>>
>
> podrias mostrar el EXPLAIN ANALYZE de la consulta?
> imagino que lo que esta pasando es que esta reescribiendo la consulta
> para que quede como:
>
> SELECT di.declaraciones_importacion_id
> FROM
> declaraciones_importacion di,
> documentos d,
> documentos_do dd
> WHERE
> di.documentos_id = d.documentos_id AND
> d.documentos_id = dd.documentos_id AND
> dd.dos_id = 180000000003039842) AS pd AND
> es_declaracion_modalidad_temporal(di.declaraciones_importacion_id)
>
> pero deberia ser obvio que evaluar las 3 primeras condiciones es menos
> costoso que la funcion...
>
> por cierto, podrias tambien mostrar la definicion de la funcion?
>
Gracias Jaime por tu amable respuesta. En efecto he corrido el select
que sugieres así:
EXPLAIN ANALYZE
SELECT di.declaraciones_importacion_id
FROM
declaraciones_importacion di,
documentos d,
documentos_do dd
WHERE
di.documentos_id = d.documentos_id AND
d.documentos_id = dd.documentos_id AND
dd.dos_id = 180000000003039842 AND
es_declaracion_modalidad_temporal(di.declaraciones_importacion_id)

con los siguientes resultados:
Nested Loop (cost=4.41..181.05 rows=1 width=8) (actual
time=376.578..616.501 rows=2 loops=1)
-> Nested Loop (cost=4.41..172.74 rows=1 width=24) (actual
time=376.487..616.314 rows=2 loops=1)
-> Bitmap Heap Scan on documentos_do dd (cost=4.41..56.60
rows=14 width=8) (actual time=0.149..0.307 rows=25 loops=1)
Recheck Cond: (dos_id = 180000000003039842::bigint)
-> Bitmap Index Scan on h_dos_id3 (cost=0.00..4.40
rows=14 width=0) (actual time=0.124..0.124 rows=25 loops=1)
Index Cond: (dos_id = 180000000003039842::bigint)
-> Index Scan using h_documentos_id7 on
declaraciones_importacion di (cost=0.00..8.28 rows=1 width=16) (actual
time=24.635..24.636 rows=0 loops=25)
Index Cond: (dd.documentos_id = di.documentos_id)
Filter:
es_declaracion_modalidad_temporal(declaraciones_importacion_id)
-> Index Scan using pk_documentos on documentos d (cost=0.00..8.29
rows=1 width=8) (actual time=0.084..0.086 rows=1 loops=2)
Index Cond: (di.documentos_id = d.documentos_id)
Total runtime: 616.616 ms
(12 filas)

rologistica=# select version();
version

-----------------------------------------------------------------------------------------------
PostgreSQL 8.2.6 on i486-pc-linux-gnu, compiled by GCC cc (GCC) 4.1.2
(Ubuntu 4.1.2-0ubuntu4)

Y en la nueva version

"Nested Loop (cost=53.02..18900.29 rows=1 width=8) (actual
time=1166617.870..1274664.912 rows=2 loops=1)"
" -> Hash Join (cost=53.02..18891.99 rows=1 width=24) (actual
time=1166518.185..1274565.194 rows=2 loops=1)"
" Hash Cond: (di.documentos_id = dd.documentos_id)"
" -> Seq Scan on declaraciones_importacion di
(cost=0.00..18761.24 rows=20725 width=16) (actual
time=1070.900..1274549.934 rows=3305 loops=1)"
" Filter:
es_declaracion_modalidad_temporal(declaraciones_importacion_id)"
" -> Hash (cost=52.86..52.86 rows=13 width=8) (actual
time=0.318..0.318 rows=25 loops=1)"
" -> Bitmap Heap Scan on documentos_do dd
(cost=4.40..52.86 rows=13 width=8) (actual time=0.114..0.264 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.092..0.092 rows=25
loops=1)"
" Index Cond: (dos_id =
180000000003039842::bigint)"
" -> Index Scan using pk_documentos on documentos d (cost=0.00..8.29
rows=1 width=8) (actual time=49.839..49.843 rows=1 loops=2)"
" Index Cond: (d.documentos_id = di.documentos_id)"
"Total runtime: 1274665.095 ms"

"PostgreSQL 8.3.3 on i486-pc-linux-gnu, compiled by GCC cc (GCC) 4.2.3
(Ubuntu 4.2.3-2ubuntu7)"

La función es

create or replace function es_declaracion_modalidad_temporal(bigint)
returns boolean as '
DECLARE
esta_declaracion_id ALIAS FOR $1;
es_temporal boolean;
esta_modalidad_id integer;
BEGIN
SELECT modalidades_id into esta_modalidad_id FROM
items_declaracion_imp WHERE declaraciones_importacion_id =
esta_declaracion_id;
SELECT es_modalidad_temporal(esta_modalidad_id) INTO es_temporal;
return es_temporal;
END;

que a su vez llama a:

create or replace function es_modalidad_temporal(int) returns boolean as '
DECLARE
esta_modalidad_id ALIAS FOR $1;
es_temporal boolean;
BEGIN
SELECT esta_modalidad_id IN (180000209, 180000198, 180000204,
180000210, 180000200, 180000206, 180000212, 180000199, 180000205,
180000211,180000196, 180000197, 180100013, 180000203) INTO es_temporal;
return es_temporal;
END;

Carlos.

Nota: Jaime las dos bases de datos fueron construidas del mismo dump.
(son idénticas)

In response to

Responses

Browse pgsql-es-ayuda by date

  From Date Subject
Next Message Edwin Quijada 2008-08-28 20:52:54 RE: NOTIFY del log ??
Previous Message Jaime Casanova 2008-08-28 17:35:13 Re: Cómo cambio el plan de ejecución de un query