Optimizar query

From: Miguel Juliÿffffe1n de la Fuente <jmdelafuente(at)yahoo(dot)com(dot)ar>
To: pgsql-es-ayuda(at)postgresql(dot)org
Subject: Optimizar query
Date: 2006-07-24 15:42:26
Message-ID: 20060724154226.50660.qmail@web52610.mail.yahoo.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-es-ayuda

Hola lista, tengo instalado "PostgreSQL 8.0.1 on i686-pc-linux-gnu, compiled by GCC 2.95.4" sobre debian, estoy tratando de ejecutar un consulta que sobre el resultado de una funcion (shortest_path devuelve aprox. 50 filas) debe unir otra tabla (calles_tmp de 30000 filas) a traves de un campo indizado en esta tabla y a su vez con otro campo de esta segunda tabla unir una tercera (calles_nombre de 1100 filas) que tambien dispone de indice por el campo buscado:

si yo ejecuto lo siguiente:

SELECT the_geom, nombre
FROM
shortest_path('SELECT id, source, target, cost FROM calles_tmp_edges where partido=45', 6001, 9960, false, false) a
inner join calles_tmp b
inner join calles_nombre n
on b.idcalle=n.idcalle
on a.edge_id=b.edge_id
where partido=45

el plan de ejecucion resulta

Merge Join (cost=2061.75..2721.72 rows=43665 width=77)
Merge Cond: ("outer".edge_id = "inner".edge_id)
-> Sort (cost=62.33..64.83 rows=1000 width=4)
Sort Key: a.edge_id
-> Function Scan on shortest_path a (cost=0.00..12.50 rows=1000 width=4)
-> Sort (cost=1999.42..2021.25 rows=8733 width=81)
Sort Key: b.edge_id
-> Hash Join (cost=63.63..1427.74 rows=8733 width=81)
Hash Cond: ("outer".idcalle = "inner".idcalle)
-> Seq Scan on calles_tmp b (cost=0.00..1223.19 rows=10719 width=72)
-> Hash (cost=61.30..61.30 rows=932 width=17)
-> Seq Scan on calles_nombre n (cost=0.00..61.30 rows=932 width=17)
Filter: (partido = 45)

que demora mas de 2 segundos y no parece ser el camino optimo.

Por esta razon tratamos de optimizarlos forzando a un nested loop de la siguiente manera:

set enable_seqscan=off; set enable_mergejoin=off; set enable_hashjoin=off; set enable_nestloop=on;

esperando que buscara a partir del resultado de la funcion las coincidencias en calles_tmp y luego a partir de este nuevo resultado las coincidencias en calles_nombre.

Pero, no. Utiliza los nested loops, pero no en el orden correcto. Primero une calles_tmp con calles_nombres y luego une el resultado de la funcion, tardando 8 segundos.
Copio el plan de ejecucion:

Nested Loop (cost=13.50..236376.67 rows=43665 width=77)
Join Filter: ("inner".edge_id = "outer".edge_id)
-> Nested Loop (cost=0.00..39870.67 rows=8733 width=81)
-> Index Scan using calles_tmp_id_calle_idq on calles_tmp b (cost=0.00..7039.83 rows=10719 width=72)
-> Index Scan using ix_idcalle on calles_nombre n (cost=0.00..3.05 rows=1 width=17)
Index Cond: ("outer".idcalle = n.idcalle)
Filter: (partido = 45)
-> Materialize (cost=13.50..23.50 rows=1000 width=4)
-> Function Scan on shortest_path a (cost=0.00..12.50 rows=1000 width=4)

Finalmente, para forzar el orden de ejecucion de las consultas, no se nos ocurrio mas que dividir las consultas guardando el resultado del primer join en una tabla temporal y luego ejecutando el segundo join.

select the_geom, idcalle
into temporary pp
from shortest_path('SELECT id, source, target, cost FROM calles_tmp_edges where partido=45', 6001, 9960, false, false) a
inner join calles_tmp b on a.edge_id=b.edge_id;

SELECT the_geom, nombre FROM pp b
inner join calles_nombre n
on b.idcalle=n.idcalle
where partido=45;

Asi, el tiempo se redujo a 640 ms.

Mis dudas son:
-- no hay alguna forma mas "elegante" de resolver el problema??
-- No le puedo indicar el orden en que debe realizar los join de alguna otra manera??
-- Y, aunque no sea mi caso, no le puedo indicar la forma de union individualmente (lo que en otro DBMS seria "inner loop join") ??

Espero sus respuestas. Muchas gracias.


---------------------------------
Preguntá. Respondé. Descubrí.
Todo lo que querías saber, y lo que ni imaginabas,
está en Yahoo! Respuestas (Beta).
Probalo ya!

Responses

Browse pgsql-es-ayuda by date

  From Date Subject
Next Message Alvaro Herrera 2006-07-24 16:18:03 Re: Optimizar query
Previous Message pedro baldovino 2006-07-24 13:45:13 Re: ayuda con query