3 votos

QGIS herramienta de muestreo de puntos más rápida que en PostGIS - ¿cómo mejorar la consulta?

Mi tabla de puntos tiene 246,338 características y la tabla de polígonos tiene 43,957 características. Estoy relacionando los valores de un atributo de los polígonos para actualizar una columna en la tabla de puntos.

Esta pregunta es similar a Speed up point sampling with ST_Value function in PostGIS, raster/vector overlay pero esa pregunta aborda específicamente el muestreo de puntos de ráster, no polígonos, utilizando ST_Value, y el tamaño óptimo de almacenamiento de mosaicos de ráster.

Ambas tablas han tenido mantenimiento realizado y tienen índices espaciales que están actualizados. Los polígonos son registros de tasas de aplicación de fertilizantes aplicadas a un campo y son bastante desordenados con muchos superpuestos:

primer plano de los polígonos de fertilizantes:

La tabla de polígonos ha sido comprobada para geometrías inválidas y estas han sido corregidas. Al correr ST_NPoints me dice que hay un promedio de solo 5 vértices por polígono así que ST_Simplify no es necesario. El tamaño promedio del polígono es de 112 m2 y van desde 0 (solo 60 de ellos) hasta 826 m2. No puedo disolver (ST_Union) polígonos en nada porque necesito los valores numéricos únicos de fertilizante de esos polígonos individuales.

He intentado dos consultas en PostGIS, pero las he abandonado después de ejecutarlas durante unas horas:

Consulta 1:

update puntos
set tasa_fert = tasa
from puntos a, polígonos b
where st_intersects(a.geom, b.geom);

Consulta 2:

with muestra_punto as (
  select tasa
  from puntos a, polígonos b
  where st_intersects(a.geom, b.geom)
)

update puntos
set tasa_fert = muestra_punto.tasa
from muestra_punto;

Tener a QGIS leyendo las tablas desde la base de datos y corriendo la herramienta de 'muestreo de puntos' solo toma un par de minutos. Sin embargo, esta no es la solución óptima por muchas razones, particularmente porque la salida debe ser guardada como un shapefile, los encabezados se truncan a 10 caracteres, y luego deben ser importados nuevamente a la base de datos, nombres de encabezado corregidos, etc.

Mis preguntas son:

  1. ¿Qué está haciendo QGIS en su algoritmo que yo no tengo en mi consulta?
  2. ¿Cómo puedo incorporar esa ventaja en mi enfoque para no tener que salir fuera de mi base de datos?

Me gustaría mantener cualquier sugerencia/solución dentro de PostGIS/QGIS.

Estoy usando PostGIS 2.4.1 y QGIS 2.18.14 en un equipo Windows 10.

EDIT: En respuesta a los comentarios de John Powell y Thingamubob, ejecuté EXPLAIN ANALYZE en las dos consultas anteriores. Ambas tablas tuvieron un vacuum/analyze realizado justo antes de correr EXPLAIN ANALYZE. Aquí está la salida para el resultado de la primera consulta:

consulta 1:

Y aquí está la salida de la segunda consulta, la que utiliza el CTE:

consulta 2:

Cada una de estas consultas EXPLAIN ANALYZE tomó alrededor de una hora para ejecutarse.

0 votos

Para este tipo de pregunta, es esencial incluir la salida de EXPLAIN. De lo contrario, es solo una suposición. Suena mucho como si el índice espacial no estuviera siendo utilizado, sin embargo, dadas las diferencias de rendimiento entre QGIS y Postgis.

0 votos

En QGIS, Processing puede generar otro formato que no sea shapefile. Especialmente en QGIS 3, podría ser aún más rápido debido al cambio a C++ de Processing.

0 votos

@Gustry, ¿puedes por favor explicar cómo se hace esto? Sé que algunas herramientas permiten la salida de un archivo temporal. Esto sería ideal, ya que podría empujar fácilmente eso de nuevo a mi base de datos postgis sin los problemas intermedios de guardarlo como un shapefile. Esta herramienta de "muestreo de puntos" en particular solo permite una opción de salida, que es un shapefile.

1voto

kal-al Puntos 506

¿Funciona mejor con un inner join en lugar de un full outer join? Espero que un inner join haga un mejor uso de los índices, mientras que el full outer join ensamblaría cada combinación posible y luego evaluaría los resultados.

(Esto fue editado con la presunción de que tiene una columna clave llamada "id" con una clave primaria de un solo campo o un índice único)

with pnt_sample as (
  select a.id, b.rate
  from points a
  JOIN polys b
  ON st_intersects(a.geom, b.geom)
)

update points p
set p.fert_rate = ps.rate
from pnt_sample ps
where p.id = ps.id;

Alternativamente:

update points
set a.fert_rate = b.rate
from points a JOIN polys b
ON st_intersects(a.geom, b.geom);

Relacionado: Adquiriendo velocidad similar a ArcGIS en PostGIS y https://stackoverflow.com/questions/17946221/sql-join-and-different-types-of-joins

Si los polígonos se superponen, entonces elegir el valor correcto puede requerir algún agrupamiento.

0 votos

Nate, tu sugerencia todavía está ejecutándose después de más de 2 horas; sin embargo, noté que si simplemente 'selecciono' en lugar de 'actualizar' usando tu consulta o cualquiera de las mías, devuelve los valores esperados en 11 segundos en todos los casos. Entonces parece que la intersección en sí no es el problema, ¿sino algo relacionado con el proceso de actualización?

0 votos

Nueva actualización - se ejecutó durante 4 o 5 horas y finalizó correctamente. Lo extraño es que tardó tanto, pero el mensaje al finalizar dijo 'La consulta se realizó correctamente en 12 min.'. Así que me pregunto por qué la discrepancia, pero esa es una pregunta completamente diferente que le haré a los expertos de SE el lunes.

0 votos

Esta consulta intentará establecer la columna fert_rate a cada entrada en pnt_sample; necesitas agregar un filtro para obtener solo una fila como parámetro de SET. ¿Puedes asegurar que ST_Intersects siempre devuelve un punto por polígono en tu Consulta 1?

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