Estoy tratando de realizar una intersección entre dos capas:
- Capa de polilínea que representa algunas carreteras (~ 5500 filas)
- 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?).