2012-07-01 13 views
5

Tengo dos tablas que me gustaría intersecar. La primera tabla representa aproximadamente 50 millones de puntos y la segunda es una capa poligonal de todos los países del mundo. Quiero obtener todos los puntos que se cruzan con ese polígono.Postgresql Spatial Query demasiado lento

SELECT d.id, d.geom 
FROM export d, world_boundaries b 
WHERE (b.cntry_name = 'UK') 
    AND d.date_inserted >= '2012-06-01' 
    AND d.geom && b.wkb_geometry 
    AND intersects(d.geom, b.wkb_geometry); 

Esta consulta es muy simple pero lleva más de 4 horas en ejecutarse. Tengo índices GIST construidos en la columna de geometría para cada tabla y tengo ANÁLISIS DE VACÍO sobre ambos. Todavía no hay aumento de rendimiento. Estoy ejecutando CENTOS 6 con Postgres 8.4 y PostGIS 1.5. ¿Alguien puede arrojar algo de luz sobre cómo acelerar las cosas? Obtengo resultados muy rápidamente al LIMITAR la consulta a 1000 a 10000 registros. Cuando trato de agarrar el conjunto de resultados completo, se arrastra. ¿Pensamientos?

ACTUALIZACIÓN: Veo ahora que tengo que refinar mi consulta como un primer paso en este proceso. Obtengo el sobre como este

select astext(st_envelope(wkb_geometry)) as e 
from world_borders 
where cntry_name = 'UK' 

Ahora, ¿cuál es la forma más eficiente de incluir/ejecutar esto como parte de toda la consulta?

+1

Cada uno de los lanzamientos recientes ha mejorado los índices GiST y GIN. Es posible que desee considerar una actualización a una nueva versión principal. Incluso podría valer la pena probar tu problema en la versión 9.2 beta, ya que incluye SP-GiST. http://www.postgresql.org/docs/9.2/static/spgist-intro.html – kgrittn

Respuesta

1

Intente ejecutarlo con EXPLAIN (y LIMIT) para ver si los índices se están utilizando en absoluto.

Dado que la comprobación de intersección real es la operación más lenta que existe, tal vez ejecutarla contra un ST_Collect de la subconsulta (todo menos la comprobación ST_Intersects) ayudaría. De esa forma solo habría una llamada y si la construcción de multigeometría es lo suficientemente rápida, el resultado neto podría ser mejor.

edit1: Bueno, resulta que no es tan óptima, ya que a menos que fuerce las coordenadas a 3d (para mantener también el id), es necesaria una búsqueda adicional para obtener el identificador de la geometría:

SELECT d.id, d.geom 
FROM 
(
    SELECT * 
    FROM 
    ( 
     SELECT ST_Collect(d.geom) 
     FROM export d, world_boundaries b 
     WHERE (b.cntry_name = 'UK') 
     AND d.date_inserted >= '2012-06-01' 
     AND d.geom && b.wkb_geometry 
    ) as c, world_boundaries b 
    WHERE (b.cntry_name = 'UK') 
    AND ST_Intersection(c.geom, b.wkb_geometry); 
) as e, export d 
WHERE (ST_Dump(e.geom)).geom = d.geom 
+2

No espere que el plan generado con un 'LIMIT 'se asemeje necesariamente al plan sin un' LIMIT '. * Puede * ser el mismo, pero podría ser completamente diferente, ya que el planificador buscará el plan más económico para devolver el número solicitado de filas, en lugar del plan más económico para devolver todas las filas. Esos a menudo difieren. – kgrittn

+0

¿Alguna posibilidad de proporcionar un ejemplo de la subconsulta ST_Collect() como con la instrucción SQL anterior? – aeupinhere

+0

@kgrittn Por supuesto, pero dudo mucho que sería más barato no usar un índice allí, por lo que debería estar bien como diagnóstico de lo que dije. – lynxlynxlynx

Cuestiones relacionadas