Performances PostGIS ST_Union

8

J'essaie d'exécuter une opération de «dissolution» dans PostGIS à l'aide de la commande ST_Union.

La couche d'entrée est certes assez grande et complexe. Par «grand», j'entends 57 771 entités, avec un nombre de sommets allant de 4 à 758 018 par entité, avec une moyenne d'environ 86 sommets par entité. Seulement environ 10 des entités ont> 10 000 sommets. Par `` complexe '', je veux dire que les polygones ont beaucoup de trous, des chevauchements désordonnés, des îles, etc. et que les grands polygones ont tendance à avoir un cadre de délimitation qui couvre la plupart des polygones plus petits, ce qui rend peut-être les index moins utiles.

Le problème est que la requête est extrêmement lente au point d'être inutilisable. J'ai lu ici le billet de 2009 de Paul qui me porte à croire que ma requête devrait toujours être assez rapide. J'utilise la commande suivante; est-ce que je fais quelque chose de manifestement faux ou inefficace?

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

Edit: j'utilise:

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 machine sur laquelle j'utilise le serveur db est une machine virtuelle sans beaucoup de puissance. Je vais essayer l'idée SET work_mem = 50000 et voir comment ça se passe!

Darren Cope
la source
Pour être clair, vous voulez l'union des géométries pour chaque combinaison de colonne1, colonne2 et colonne3? Pouvez-vous définir grand, complexe et lent et qu'est-ce que l'explication montre?
John Powell
1
John; oui, je veux l'union pour chaque combinaison des colonnes 1,2 et 3. Je ne sais pas comment quantifier les «grands» - mais c'est un certain nombre de polygones très complexes (plusieurs sommets) avec des chevauchements et des îles en désordre, etc. Je vais devoir faire des recherches sur «expliquer» avant de pouvoir répondre à votre dernière question!
Darren Cope
Explain pourrait ne pas être très utile dans ce cas, car il mesure principalement le temps de recherche de disque pour lire réellement les lignes, en fonction des statistiques de table, des index, etc. Il ne prend pas en compte le temps d'exécution d'une fonction comme ST_Union, qui dépend de la complexité des polygones, du nombre de chevauchements, etc.
John Powell
1
Veuillez modifier la question pour ajouter des détails.
Vince
1
Cela dépend aussi de votre version GEOS. De meilleurs algorithmes d'agrégation ont été introduits dans la version 3.1.0.
Scro

Réponses:

3

Ce type d'opération utilise beaucoup de mémoire de travail si je me souviens bien, vous devez donc vous assurer que vous n'êtes pas aux paramètres par défaut pour ce qui est assez bas;

Essayez quelque chose comme

SET work_mem=50000;
Then run your query

Vous voudrez peut-être jouer avec ce paramètre de workmem

Vous voudrez également le vider dans une table - pas la sortie à l'écran. Je suppose que vous le savez déjà

Autres choses que vous souhaitez vérifier - que je mets dans les commentaires mais que je répéterai ici:

Il y a deux choses qui ont amélioré la vitesse de l'union - la chose en cascade que vous avez signalée, et pour le nombre de polygones, l'accumulation de tableaux plus rapide (qui, je pense, est venue dans PostGIS 1.5 (peut-être 1,4 ne se souvient pas), PostgreSQL 8.4 (migth be 9.0 can ne me souviens pas)). De plus, même un nouveau GEOS ne fera pas de bien si vous utilisez <PostGIS 1.4

Il est donc important de vérifier la version postgis et la version postgresql

SELECT postgis_full_version() || ' ' || version();
LR1234567
la source
Il y en a aussi ST_MemUnion. Utilise moins de mémoire, plus de processeur: postgis.net/docs/ST_MemUnion.html
Scro
3
Cette fonction est assez ancienne. Je pense que la nouvelle implémentation ST_Union conserve en fait mieux la mémoire que cette fonction.
LR1234567
2

Avant même d'exécuter ST_Union

ANALYSER votre base de données pour mettre à jour les statistiques des requêtes.

Videz votre base de données pour la purger si vous n'exécutez pas déjà Autovacuum. Vérifiez vos paramètres principaux pour vous assurer qu'ils sont définis sur des valeurs sensibles.

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

Testez la modification de work_mem : augmentez-la à 8 Mo, 32 Mo, 256 Mo, 1 Go. Est-ce que cela fait une différence?

* 32 Mo par défaut

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

Mapperz
la source
Merci. Je viens d'essayer ANALYZE, VACUUM et d'augmenter shared_buffers et effective_cache_size, et j'ai eu le même problème. Je continuerai de peaufiner le temps.
Darren Cope
@DarrenCope des progrès? Je fais face au même problème.
Michal Zimmermann
@zimmi; malheureusement pas :( Je suis toujours là où j'étais avant! Faites-vous exactement la même chose? Peut-être partager un exemple et voir s'il y a des similitudes
Darren Cope
1
@DarrenCope ST_Buffer (St_Collect (wkb_geometry), 0) semble être beaucoup plus rapide et correspond à mes besoins. Cela pourrait aussi vous aider.
Michal Zimmermann