PostGIS ST_Union Performance

8

Estoy tratando de ejecutar una operación 'disolver' en PostGIS usando el comando ST_Union.

La capa de entrada es ciertamente bastante grande y compleja. Por "grande" me refiero a 57.771 entidades, con un número de vértices que van de 4 a 758.018 por entidad, con un promedio de alrededor de 86 vértices por entidad. Solo alrededor de 10 de las características tienen> 10,000 vértices. Por "complejo" quiero decir que los polígonos tienen muchos agujeros, superposiciones desordenadas, islas, etc., y que los polígonos grandes tienden a tener un cuadro delimitador que cubre muchos de los polígonos más pequeños, tal vez los índices de desgarre sean menos útiles.

El problema es que la consulta es extremadamente lenta hasta el punto de ser inutilizable. Leí la publicación de Paul de 2009 aquí que me llevó a creer que mi consulta aún debería ser bastante rápida. Estoy usando el siguiente comando; ¿Estoy haciendo algo descaradamente incorrecto o ineficiente?

SELECT  ST_Union(f.geom) as geom, column1,column2,column3
FROM "inputlayer" As f 
GROUP BY column1,column2,column3

Editar: estoy usando:

POSTGIS="2.1.4 r12966" GEOS="3.3.3-CAPI-1.7.4" PROJ="Rel. 4.7.1, 23 September 2009" GDAL="GDAL 2.0.0dev, released 2014/04/16" LIBXML="2.7.8" LIBJSON="UNKNOWN" TOPOLOGY RASTER PostgreSQL 9.3.5 on x86_64-unknown-linux-gnu, compiled by gcc (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3, 64-bit

La máquina en la que estoy ejecutando el servidor db es una máquina virtual sin mucha potencia. ¡Probaré la idea SET work_mem = 50000 y veré cómo van las cosas!

Darren Cope
fuente
Para ser claros, ¿quieres la unión de las geometrías para cada combinación de column1, column2 y column3? ¿Puedes definir grande, complejo y lento y qué se explica mostrar?
John Powell el
1
Juan; sí, quiero la unión para cada combinación de las columnas 1,2 y 3. No estoy seguro de cómo cuantificar 'grande', pero es un número de polígonos muy complejos (muchos vértices) con superposiciones e islas desordenadas, etc. ¡Tendré que investigar un poco sobre 'explicar' antes de que pueda responder su última pregunta!
Darren Cope
Explicar puede no ser muy útil en este caso, ya que mide principalmente el tiempo de búsqueda del disco para leer realmente las filas, en función de las estadísticas de la tabla, los índices, etc. No tiene en cuenta el tiempo de ejecución de una función como ST_Union, que depende de la complejidad de los polígonos, número de superposiciones, etc.
John Powell
1
Edite la pregunta para agregar detalles.
Vince
1
Depende también de su versión GEOS. Se introdujeron mejores algoritmos de agregación en la versión 3.1.0.
Scro

Respuestas:

3

Según recuerdo, este tipo de operación utiliza mucha memoria de trabajo, por lo que debe asegurarse de no estar en la configuración predeterminada para esto, que es bastante baja;

Intenta algo como

SET work_mem=50000;
Then run your query

Es posible que desee jugar con esa configuración de workmem

También querrá volcar eso en una tabla, no en la pantalla. Asumo que ya lo sabes

Otras cosas que desea verificar, que puse en los comentarios pero que repetiré aquí:

Hay dos cosas que mejoraron la velocidad de unión: la cosa en cascada que señaló, y para el recuento de polígonos, la acumulación de matriz más rápida (que creo que vino en PostGIS 1.5 (podría ser 1.4 no se puede recordar), PostgreSQL 8.4 (migth be 9.0 puede No recuerdo)). Además, incluso un GEOS más nuevo no funcionará si está ejecutando <PostGIS 1.4

Por lo tanto, es importante verificar tanto la versión postgis como la versión postgresql

SELECT postgis_full_version() || ' ' || version();
LR1234567
fuente
También existe ST_MemUnion. Utiliza menos memoria, más procesador: postgis.net/docs/ST_MemUnion.html
Scro
3
Esa función es bastante antigua. Creo que la nueva implementación de ST_Union en realidad conserva la memoria mejor que esa función.
LR1234567
2

Incluso antes de ejecutar ST_Union

ANALICE su base de datos para actualizar las estadísticas de consultas.

VACÍE su base de datos para purgarla si aún no está ejecutando Autovacuum. Verifique su configuración principal para asegurarse de que esté establecida en valores razonables.

shared_buffers should be 10% to 25% of available RAM
effective_cache_size should be 75% of available RAM 

Prueba cambiando work_mem : increméntelo a 8MB, 32MB, 256MB, 1GB. ¿Hace alguna diferencia?

* 32 MB es predeterminado

fuente: https://wiki.postgresql.org/wiki/Tuning_Your_PostgreSQL_Server

Mapperz
fuente
Gracias. Acabo de probar ANALYZE, VACUUM e incrementando shared_buffers y efectividad_cache_size, y tuve el mismo problema. Seguiré ajustando según lo permita el tiempo.
Darren Cope
@DarrenCope ¿algún progreso? Estoy enfrentando el mismo problema.
Michal Zimmermann
@zimmi; desafortunadamente no :( ¡Todavía estoy donde estaba antes! ¿Estás haciendo exactamente lo mismo? Quizás comparta un ejemplo y vea si hay alguna similitud
Darren Cope
1
@DarrenCope ST_Buffer (St_Collect (wkb_geometry), 0) parece ser mucho más rápido y se ajusta a mis necesidades. Podría ayudarte también.
Michal Zimmermann