Loading [MathJax]/jax/element/mml/optable/BasicLatin.js

25 votos

Problema del vecino más próximo en Postgis 2.0 utilizando el índice GIST (<-> función)

Estoy tratando de utilizar Postgis 2.0 nueva función <-> (Geometría Distancia Centroide) con el fin de calcular, para cada fila de mi tabla (cosn1), la distancia al polígono más cercano de la misma clase.

Intentaba utilizar el siguiente código:

WITH index_query AS (
  SELECT g1.gid As ref_gid, ST_Distance(g1.the_geom,g2.the_geom) As ENN    
    FROM "cosn1" As g1, "cosn1" As g2   
    WHERE g1.gid <> g2.gid AND g1.class = g2.class
    ORDER BY g1.gid, g1.the_geom <-> g2.the_geom) 
SELECT DISTINCT ON (ref_gid) ref_gid, ENN 
    FROM index_query
ORDER BY ref_gid, ENN;

Pero entonces me doy cuenta de la advertencia:

Nota: El índice sólo se activa si una de las geometrías es una constante (no en una subconsulta/cte). por ejemplo, 'SRID=3005;POINT(1011102 450541)'::geometry en lugar de a.geom

Esto significa que el índice no se utilizará en absoluto, y la consulta tardará casi el mismo tiempo que antes de utilizarlo:

SELECT DISTINCT ON(g1.gid)  g1.gid As ref_gid, ST_Distance(g1.the_geom,g2.the_geom) As ENN    
    FROM "cosn1" As g1, "cosn1" As g2   
    WHERE g1.gid <> g2.gid AND g1.class = g2.class
    ORDER BY g1.gid, ST_Distance(g1.the_geom,g2.the_geom)

¿Puede alguien indicarme una solución que me permita mejorar el rendimiento de mi consulta?

Muchas gracias.

1voto

naknode Puntos 143

Haciendo algunas pruebas en mi máquina sugiero que este operador <-> no funciona correctamente. No estoy seguro de que es un error, pero informó de cero distancia en geometrías no superpuestas.

He probado las optimizaciones de consulta SQL tradicionales justas. Desde esos resultados inesperados con <-> operador lo reemplazo con st_centroid. Obtuve resultados mucho mejores en velocidad.

Espero que la semántica con st_overlaps siga igual. Al menos esto fue lo que entendí de la documentación sobre <->

De docs en Postigs <->

Para otros tipos de geometría, la distancia entre el punto flotante de punto flotante.

En mis datos de prueba con ~5.5k polígonos conseguí aumentar la velocidad de ~1000 segundos a ~5 segundos sin indexación espacial.

Veo que hay gente que usa DISTINCT ON para hacer agrupaciones pero no existe el grupo por para eliminar duplicados.

Su consulta con optimizaciones SQL estándar sin el error st_centroid introducido

select g1.gid, min( st_distance( g1.the_geom, g2.the_geom ) ) AS enn
FROM 
  "cosn1" AS g1, "cosn1" AS g2
WHERE
  g1.gid <> g2.gid
  AND g1.class = g2.class
  AND g1.the_geom && g2.the_geom
GROUP BY
  g1.gid

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X