Próbuję wykonać przecięcie dwóch warstw:
- Warstwa polilinii reprezentująca niektóre drogi (~ 5500 wierszy)
- Warstwa wielokąta reprezentująca bufory o nieregularnych kształtach wokół różnych punktów zainteresowania (~ 47 000 rzędów)
Ostatecznie staram się przypiąć polilinie do wielu (czasami nakładających się) buforów, a następnie zsumować całkowitą długość jezdni zawartą w każdym buforze.
Problem polega na tym, że wszystko działa w zwolnionym tempie. Nie jestem pewien, jak długo to powinno potrwać, ale po prostu przerwałem zapytanie po> 34 godzinach. Mam nadzieję, że ktoś może wskazać, gdzie popełniłem błąd w zapytaniu SQL, lub wskazać lepszy sposób na zrobienie tego.
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;
Mam indeks GiST utworzony dla oryginalnej tabeli dróg i (na wszelki wypadek?) Utwórz indeks przed utworzeniem drugiej tabeli.
Plan zapytań z PGAdmin III wygląda następująco, ale obawiam się, że nie mam dużych umiejętności interpretowania go:
"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)"
Czy ta operacja jest po prostu skazana na kilka dni? Obecnie używam tego na PostGIS dla Windows, ale teoretycznie mógłbym rzucić więcej sprzętu na problem, umieszczając go na Amazon EC2. Widzę jednak, że zapytanie używa tylko jednego rdzenia na raz (czy istnieje sposób, aby zwiększyć jego wykorzystanie?).