Wolne zapytanie ST_Intersection


11

Próbuję wykonać przecięcie dwóch warstw:

  1. Warstwa polilinii reprezentująca niektóre drogi (~ 5500 wierszy)
  2. 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?).


Na czym działa Postgis? Czynnikiem może być system operacyjny i procesor.
Mapperz

Cześć Mapperz: System operacyjny to Windows 7, procesor to Core 2 Duo, pamięć to 4 GB (w systemie Windows z 32-bitowym PGSQL / PostGIS)
Peter

Odpowiedzi:


6

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?


Cześć LR1234567: „POSTGIS =” 1.5.2 ”GEOS =„ 3.2.2-CAPI-1.6.2 ”PROJ =„ Rel. 4.6.1, 21 sierpnia 2008 r. „LIBXML =" 2.7.6 „USE_STATS”; „PostgreSQL 9.0.3, skompilowany przez kompilację Visual C ++ w wersji 1500, 32-bit” (teraz uruchomione jest inne zapytanie)
Peter

Zapytanie Max działało szybciej niż się spodziewałem: maxp = 2030 Podejrzewam, że to dość drobnoziarniste?
Peter

1
2,030 faktycznie nie jest zły. Możliwe, że po prostu masz wiele przecinających się wielokątów. Ogólnie przecięcie jest częścią najwolniejszą. Spróbuj policzyć, ile rekordów faktycznie przecina się - może być ogromna.
LR1234567

WYBIERZ count (*) FROM public. "Roads" b, public. "Buffer1KM" z WHERE ST_Intersects (b.the_geom, z.the_geom);
LR1234567

1
Czy 910 978 jest ogromny? To miło, że zaczynam od nowej technologii - nie mam normatywnych oczekiwań :-)
Peter

1

Dziękuję, to brzmi jak dobra rada. Niektóre problemy z systemem Windows, takie jak kara za rozwidlenie (), nie powinny stanowić problemu, ponieważ uruchamiam pojedyncze połączenie, prawda? Uruchom także VACUUM ANALYZE. Jednak nie zgłębiłem jeszcze żadnej optymalizacji wydajności.
Peter

1
Bufory współdzielone i work_mem zazwyczaj robią największą różnicę. W przypadku shared_buffers jesteś trochę bardziej ograniczony, ile możesz zwiększyć w
Windowsie

shared_buffers był już włączony, ale work_mem był wyłączony. Dodałem teraz 1 GB pamięci roboczej.
Peter

1

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


Linki są zepsute, czy odnosi się to do PostGIS w akcji czy do książki kucharskiej PostGIS?
HeikkiVesanto

1
ah masz rację. Były to linki do pierwszej edycji PostGIS w akcji - które wówczas były aktualne. Kiedy wprowadziliśmy drugą edycję, musieliśmy zmienić strukturę linków. Stare linki, o których mowa, są teraz tutaj: postgis.us/chapters_edition_1
LR1234567

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.