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?).
źródło
Odpowiedzi:
Piotr,
Jakiej wersji PostGIS, GEOS i PostgreSQL używasz?
zrobić
WYBIERZ postgis_full_version (), version ();
Wprowadzono wiele ulepszeń między 1.4 a 1.5 i GEOS 3.2+ dla tego rodzaju rzeczy.
A także ile wierzchołków mają twoje wielokąty?
Zrób
WYBIERZ Max (ST_NPoints (the_geom)) Jako maxp z czegoś;
Aby zrozumieć swój najgorszy scenariusz. Taka niska prędkość jest często spowodowana zbytnio ziarnistymi geometriami. W takim przypadku możesz najpierw uprościć.
Czy dokonałeś również optymalizacji pliku postgresql.conf?
źródło
pomocna odpowiedź wymiany stosu: /programming/1162206/why-is-postgresql-so-slow-on-windows
Strojenie postgres: http://wiki.postgresql.org/wiki/Performance_Optimization
z doświadczenia polecam VACUUM ANALYZE
źródło
Bezwstydna wtyczka :) Może pomóc przeczytać rozdział 8 i rozdział 9 naszej książki. Po prostu rozgrzej prasy. W tych rozdziałach omawiamy wiele tego rodzaju pytań.
http://www.postgis.us/chapter_08
http://www.postgis.us/chapter_09
źródło
Zobacz dwie wskazówki dotyczące optymalizacji zapytania przestrzennego. Działają mi bardzo dobrze. http://kb.zillionics.com/optimize-spatial-query/
źródło