Requête lente ST_Intersection


11

J'essaie de réaliser une intersection entre deux couches:

  1. Couche de polyligne représentant certaines routes (~ 5500 lignes)
  2. Couche de polygones représentant des tampons de forme irrégulière autour de divers points d'intérêt (~ 47 000 lignes)

En fin de compte, ce que j'essaie de faire, c'est d'attacher les polylignes à ces nombreux tampons (qui se chevauchent parfois), puis de résumer la longueur totale de la chaussée contenue dans chaque tampon.

Le problème est que les choses tournent lentement. Je ne sais pas combien de temps cela devrait prendre, mais j'ai juste abandonné ma requête après> 34 heures. J'espère que quelqu'un pourra soit signaler où j'ai fait une erreur avec ma requête SQL, soit me montrer une meilleure façon de procéder.

CREATE TABLE clip_roads AS

SELECT 
  ST_Intersection(b.the_geom, z.the_geom) AS clip_geom,
  b.*

FROM 
  public."roads" b, 
  public."buffer1KM" z

WHERE ST_Intersects(b.the_geom, z.the_geom);


CREATE INDEX "clip_roads_clip_geom_gist"
  ON "clip_roads"
  USING gist
  (clip_geom);



CREATE TABLE buffer1km_join AS

SELECT
  z.name, z.the_geom,
  sum(ST_Length(b.clip_geom)) AS sum_length_m

FROM
  public."clip_roads" b,
  public."buffer1KM" z

WHERE
  ST_Contains(z.the_geom, b.the_geom)

GROUP BY z.name, z.the_geom;

J'ai un index GiST créé pour la table des routes d'origine et (juste pour être sûr?) Créer un index avant de créer la deuxième table.

Le plan de requête de PGAdmin III ressemble à ceci, bien que je crains de ne pas avoir beaucoup de compétences pour l'interpréter:

"Nested Loop  (cost=0.00..29169.98 rows=35129 width=49364)"
"  Output: st_intersection(b.the_geom, z.the_geom), b.gid, b.geo_id, b.address_l, b.address_r, b.lf_name, b.lfn_id, b.lfn_name, b.lfn_type_c, b.lfn_type_d, b.lfn_dir_co, b.lfn_dir_de, b.lfn_desc, b.oe_flag_l, b.oe_flag_r, b.fcode_desc, b.fcode, b.fnode, b.tnode, b.metrd_num, b.lo_num_l, b.lo_n_suf_l, b.hi_num_l, b.hi_n_suf_l, b.lo_num_r, b.lo_n_suf_r, b.hi_num_r, b.hi_n_suf_r, b.juris_code, b.dir_code, b.dir_code_d, b.cp_type, b.length, b.the_geom"
"  Join Filter: _st_intersects(b.the_geom, z.the_geom)"
"  ->  Seq Scan on public."roads" b  (cost=0.00..306.72 rows=5472 width=918)"
"        Output: b.gid, b.geo_id, b.address_l, b.address_r, b.lf_name, b.lfn_id, b.lfn_name, b.lfn_type_c, b.lfn_type_d, b.lfn_dir_co, b.lfn_dir_de, b.lfn_desc, b.oe_flag_l, b.oe_flag_r, b.fcode_desc, b.fcode, b.fnode, b.tnode, b.metrd_num, b.lo_num_l, b.lo_n_suf_l, b.hi_num_l, b.hi_n_suf_l, b.lo_num_r, b.lo_n_suf_r, b.hi_num_r, b.hi_n_suf_r, b.juris_code, b.dir_code, b.dir_code_d, b.cp_type, b.length, b.the_geom"
"  ->  Index Scan using "buffer1KM_index_the_geom" on public."buffer1KM" z  (cost=0.00..3.41 rows=1 width=48446)"
"        Output: z.gid, z.objectid, z.facilityid, z.name, z.frombreak, z.tobreak, z.postal_cod, z.pc_area, z.ct_id, z.da_id, z.taz_id, z.edge_poly, z.cchs_0708, z.tts_06, z.the_geom"
"        Index Cond: (b.the_geom && z.the_geom)"

Cette opération est-elle vouée à être exécutée pendant plusieurs jours? J'exécute actuellement cela sur PostGIS pour Windows, mais je pourrais en théorie jeter plus de matériel sur le problème en le mettant sur Amazon EC2. Cependant, je vois que la requête n'utilise qu'un seul noyau à la fois (existe-t-il un moyen de le faire utiliser davantage?).


Sur quoi Postgis fonctionne-t-il? Le système d'exploitation et le processeur peuvent être un facteur.
Mapperz

Salut Mapperz: le système d'exploitation est Windows 7, le processeur est Core 2 Duo, la mémoire est de 4 Go (étant Windows, exécutant PGSQL / PostGIS 32 bits)
Peter

Réponses:


6

Peter,

Quelle version de PostGIS, GEOS et PostgreSQL utilisez-vous?
fait une

SELECT postgis_full_version (), version ();

De nombreuses améliorations ont été apportées entre 1.4 et 1.5 et GEOS 3.2+ pour ce genre de chose.

Aussi combien de sommets ont vos polygones?

Fait une

SELECT Max (ST_NPoints (the_geom)) Comme maxp FROM quelque chose;

Pour avoir une idée de votre pire scénario. Une vitesse aussi lente est souvent causée par des géométries trop finement grainées. Dans ce cas, vous voudrez peut-être simplifier en premier.

Avez-vous également optimisé votre fichier postgresql.conf?


Salut LR1234567: "POSTGIS =" 1.5.2 "GEOS =" 3.2.2-CAPI-1.6.2 "PROJ =" Rel. 4.6.1, 21 août 2008 "LIBXML =" 2.7.6 "USE_STATS"; "PostgreSQL 9.0.3, compilé par Visual C ++ build 1500, 32 bits" (exécutant maintenant l'autre requête)
Peter

La requête Max s'est exécutée plus rapidement que prévu: maxp = 2030 Je pense que c'est assez fin?
Peter

1
2.030 n'est pas mauvais en fait. Il se peut que vous ayez juste beaucoup de polygones qui se croisent. Généralement, l'intersection est la partie la plus lente. Essayez de compter le nombre d'enregistrements qui se croisent réellement - cela pourrait être énorme.
LR1234567

SELECT count (*) FROM public. "Routes" b, public. "Buffer1KM" z WHERE ST_Intersects (b.the_geom, z.the_geom);
LR1234567

1
910 978 est-il énorme? C'est la bonne chose à propos du démarrage d'une nouvelle technologie - je n'ai aucune attente normative :-)
Peter

1

réponse d'échange de pile utile: /programming/1162206/why-is-postgresql-so-slow-on-windows

Optimisation des postgres: http://wiki.postgresql.org/wiki/Performance_Optimization

de l'expérience recommande ANALYSE SOUS VIDE


Merci, cela ressemble à de bons conseils. Certains des problèmes de Windows tels que la pénalité fork () ne devraient pas être un problème ici car j'exécute une seule connexion, non? Vous avez également exécuté VACUUM ANALYZE. Je n'ai pas encore creusé d'optimisation des performances.
Peter

1
shared_buffers et work_mem font généralement la différence. Pour shared_buffers, vous êtes un peu plus limité dans la mesure où vous pouvez le faire sur Windows que sur Linux
LR1234567

shared_buffers était déjà activé, mais work_mem était désactivé. J'ai ajouté 1 Go de mémoire de travail maintenant.
Peter

1

Prise sans vergogne :) Pourrait aider à lire les chapitres 8 et 9 de notre livre. Tout juste sorti des presses. Nous couvrons beaucoup de ce genre de questions dans ces chapitres.

http://www.postgis.us/chapter_08

http://www.postgis.us/chapter_09


Les liens sont rompus, cela fait-il référence à PostGIS en action ou au livre de recettes PostGIS?
HeikkiVesanto

1
ah tu as raison. Il s'agissait de liens vers la première édition de PostGIS in Action - qui étaient valables à l'époque. Lorsque nous avons introduit la 2e édition, nous avons dû changer la structure des liens. Les anciens liens auxquels il est fait référence sont maintenant ici: postgis.us/chapters_edition_1
LR1234567

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.