Interrogazione lenta ST_Intersection


11

Sto cercando di eseguire un'intersezione tra due livelli:

  1. Strato polilinea che rappresenta alcune strade (~ 5500 righe)
  2. Strato poligonale che rappresenta buffer di forma irregolare attorno a vari punti di interesse (~ 47.000 righe)

Alla fine, quello che sto cercando di fare è agganciare le polilinee a questi molti buffer (a volte sovrapposti) e quindi riassumere la lunghezza totale della carreggiata contenuta in ciascun buffer.

Il problema è che le cose funzionano LENTO. Non sono sicuro del tempo necessario, ma ho interrotto la mia query dopo> 34 ore. Spero che qualcuno possa indicare dove ho commesso un errore con la mia query SQL o indicarmi un modo migliore per farlo.

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;

Ho un indice GiST creato per la tabella delle strade originale e (solo per sicurezza?) Creo un indice prima di creare la seconda tabella.

Il piano di query di PGAdmin III è simile al seguente, anche se temo di non avere molta abilità nell'interpretarlo:

"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)"

Questa operazione è destinata a durare diversi giorni? Attualmente sto eseguendo questo su PostGIS per Windows, ma in teoria potrei gettare più hardware al problema installandolo su Amazon EC2. Tuttavia, vedo che la query utilizza solo un core alla volta (esiste un modo per farne un uso maggiore?).


Cosa funziona Postgis? Sistema operativo e processore potrebbero essere un fattore.
Mapperz

Ciao Mapperz: il sistema operativo è Windows 7, la CPU è Core 2 Duo, la memoria è 4 GB (essendo Windows, con PGSQL / PostGIS a 32 bit)
Peter,

Risposte:


6

Peter,

Quale versione di PostGIS, GEOS e PostgreSQL stai usando?
fare un

SELEZIONA postgis_full_version (), version ();

Sono stati apportati molti miglioramenti tra 1.4 e 1.5 e GEOS 3.2+ per questo tipo di cose.

Inoltre, quanti vertici hanno i tuoi poligoni?

Fare un

SELECT Max (ST_NPoints (the_geom)) Come maxp FROM a volte;

Per avere un'idea del tuo scenario peggiore. Una velocità lenta come questa è spesso causata da geometrie troppo granulose. Nel qual caso potresti voler prima semplificare.

Hai anche ottimizzato il tuo file postgresql.conf?


Ciao LR1234567: "POSTGIS =" 1.5.2 "GEOS =" 3.2.2-CAPI-1.6.2 "PROJ =" Rel. 4.6.1, 21 agosto 2008 "LIBXML =" 2.7.6 "USE_STATS"; "PostgreSQL 9.0.3, compilato da Visual C ++ build 1500, 32-bit" (eseguendo ora l'altra query)
Peter

La query Max è stata eseguita più velocemente di quanto mi aspettassi: maxp = 2030 Sospetto che sia abbastanza fine?
Peter,

1
2.030 non è male in realtà. Potresti avere solo molti poligoni che si intersecano. Generalmente l'intersezione è la parte più lenta .. Prova a fare un conto su quanti record si intersecano effettivamente - potrebbe essere enorme.
LR1234567,

SELEZIONA contare (*) DA pubblico. "Strade" b, pubblico. "Buffer1KM" z DOVE ST_Intersects (b.the_geom, z.the_geom);
LR1234567,

1
910.978 è enorme? Questa è la cosa bella dell'avvio di una nuova tecnologia: non ho aspettative normative :-)
Peter,

1

utile risposta per lo scambio di stack: /programming/1162206/why-is-postgresql-so-slow-on-windows

Ottimizzazione dei postgres: http://wiki.postgresql.org/wiki/Performance_Optimization

dall'esperienza raccomandiamo ANALISI SOTTOVUOTO


Grazie, sembra un buon consiglio. Alcuni dei problemi di Windows come la fork () non dovrebbero essere un problema qui perché sto eseguendo una singola connessione, giusto? Inoltre, hai eseguito VACUUM ANALYZE. Tuttavia, non ho ancora approfondito l'ottimizzazione delle prestazioni.
Peter,

1
shared_buffers e work_mem generalmente fanno la differenza. Per shared_buffers sei un po 'più limitato di quanto puoi farlo su Windows che su Linux
LR1234567

shared_buffers era già attivo, ma work_mem era disattivato. Ho aggiunto 1 GB di mem di lavoro ora.
Peter,

1

Spina senza vergogna :) Potrebbe aiutare a leggere il capitolo 8 e il capitolo 9 del nostro libro. Appena caldo dalle macchine da stampa. Copriamo molte di queste domande in questi capitoli.

http://www.postgis.us/chapter_08

http://www.postgis.us/chapter_09


I collegamenti sono interrotti, si riferisce a PostGIS in azione o al ricettario PostGIS?
HeikkiVesanto,

1
ah hai ragione. Questi erano collegamenti alla prima edizione di PostGIS in azione, che allora erano validi. Quando abbiamo introdotto la seconda edizione, abbiamo dovuto modificare la struttura dei collegamenti. I vecchi link a cui si fa riferimento sono ora qui: postgis.us/chapters_edition_1
LR1234567

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.