Consulta lenta ST_Intersection

11

Estoy tratando de realizar una intersección entre dos capas:

  1. Capa de polilínea que representa algunas carreteras (~ 5500 filas)
  2. Capa de polígono que representa buffers de forma irregular alrededor de varios puntos de interés (~ 47,000 filas)

En última instancia, lo que estoy tratando de hacer es recortar las polilíneas a estos muchos búferes (a veces superpuestos), y luego resumir la longitud total de la carretera contenida dentro de cada búfer.

El problema es que las cosas están funcionando LENTO. No estoy seguro de cuánto tiempo debería tomar esto, pero acabo de cancelar mi consulta después de> 34 horas. Espero que alguien pueda señalar dónde he cometido algún error con mi consulta SQL o puede indicarme una mejor manera de hacerlo.

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;

Tengo un índice GiST creado para la tabla de carreteras original, y (¿solo para estar seguro?) Creo un índice antes de crear la segunda tabla.

El plan de consulta de PGAdmin III se ve así, aunque me temo que no tengo mucha habilidad para 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)"

¿Esta operación está condenada a ejecutarse durante varios días? Actualmente estoy ejecutando esto en PostGIS para Windows, pero en teoría podría lanzar más hardware al problema al instalarlo en Amazon EC2. Sin embargo, veo que la consulta solo usa un núcleo a la vez (¿hay alguna manera de hacer que use más?).

Peter
fuente
¿En qué se está ejecutando Postgis? El sistema operativo y el procesador pueden ser un factor.
Mapperz
Hola Mapperz: el sistema operativo es Windows 7, la CPU es Core 2 Duo, la memoria es de 4 GB (siendo Windows, ejecutando PGSQL / PostGIS de 32 bits)
Peter

Respuestas:

6

Peter

¿Qué versión de PostGIS, GEOS y PostgreSQL está utilizando?
hacer un

SELECCIONE postgis_full_version (), version ();

Se han realizado muchas mejoras entre 1.4 y 1.5 y GEOS 3.2+ para este tipo de cosas.

Además, ¿cuántos vértices tienen tus polígonos?

Hacer un

SELECT Max (ST_NPoints (the_geom)) Como maxp FROM sometable;

Para tener una idea de su peor escenario. Una velocidad lenta como esta a menudo es causada por geometrías que finalmente son demasiado finas. En cuyo caso es posible que desee simplificar primero.

¿También ha realizado optimizaciones en su archivo postgresql.conf?

LR1234567
fuente
Hola LR1234567: "POSTGIS =" 1.5.2 "GEOS =" 3.2.2-CAPI-1.6.2 "PROJ =" Rel. 4.6.1, 21 de agosto de 2008 "LIBXML =" 2.7.6 "USE_STATS"; "PostgreSQL 9.0.3, compilado por Visual C ++ build 1500, 32-bit" (ejecutando la otra consulta ahora)
Peter
La consulta Max se ejecutó más rápido de lo que esperaba: maxp = 2030 ¿Sospecho que es bastante fino?
Peter
1
2,030 no es malo en realidad. Podría ser que solo tienes muchos polígonos que se cruzan. En general, la intersección es la parte más lenta. Intente hacer un recuento de cuántos registros se cruzan realmente; podría ser enorme.
LR1234567
SELECCIONAR recuento (*) DESDE public. "Carreteras" b, public. "Buffer1KM" z DONDE ST_Intersects (b.the_geom, z.the_geom);
LR1234567
1
¿910,978 es enorme? Esto es lo bueno de comenzar con una nueva tecnología: no tengo expectativas normativas :-)
Peter
1

útil respuesta de intercambio de pila: /programming/1162206/why-is-postgresql-so-slow-on-windows

Ajuste de postgres: http://wiki.postgresql.org/wiki/Performance_Optimization

por experiencia recomendar ANÁLISIS DE VACÍO

Mapperz
fuente
Gracias, eso suena como un buen consejo. Algunos de los problemas de Windows, como la penalización fork (), no deberían ser un problema aquí porque estoy ejecutando una sola conexión, ¿verdad? Además, he ejecutado VACUUM ANALYZE. Sin embargo, aún no he profundizado en la optimización del rendimiento.
Peter
1
shared_buffers y work_mem generalmente hacen la mayor diferencia. Para shared_buffers, está un poco más limitado cuánto puede subir eso en Windows que en Linux
LR1234567
shared_buffers ya estaba activado, pero work_mem estaba desactivado. He agregado 1 GB de memoria de trabajo ahora.
Peter
1

Plug desvergonzado :) Podría ayudar a leer el capítulo 8 y el capítulo 9 de nuestro libro. Recién salido de las prensas. Cubrimos muchas de estas preguntas en esos capítulos.

http://www.postgis.us/chapter_08

http://www.postgis.us/chapter_09

LR1234567
fuente
Los enlaces están rotos, ¿se refiere a PostGIS en acción o al libro de cocina de PostGIS?
HeikkiVesanto
1
ah tienes razon Esos eran enlaces a la primera edición de PostGIS en acción, que eran válidos en aquel entonces. Cuando presentamos la segunda edición, tuvimos que cambiar la estructura del enlace. Los enlaces antiguos a los que se hace referencia ahora están aquí: postgis.us/chapters_edition_1
LR1234567