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!
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 |