PostGIS wolno ST_Intersection

Sep 25 2020

Próbuję uzyskać przecięcia między jedną linią prostą a kilkoma liniami konturowymi. Używając poniższego SQL:

DROP TABLE IF EXISTS v_line;
SELECT st_geomfromtext('linestring(103.492217095662 30.9300260311043,103.494817217263 30.9200436767033)',4326) as geom INTO v_line;
SELECT a.gid,a.height, ST_AsText(ST_Intersection(b.geom, a.geom)) 
FROM contour_cb9eba as a,v_line as b 
WHERE ST_Intersects(b.geom,a.geom);

Ale zapytanie trwa dziesiątki sekund. Dostroiłem postgresql, nie pomaga. Mam utworzony indeks na stole konturowym, nie pomaga. wyjaśnienie znajduje się poniżej:

Nested Loop  (cost=0.14..665.47 rows=37 width=44)
  ->  Seq Scan on v_line b  (cost=0.00..23.60 rows=1360 width=32)
  ->  Index Scan using contour_cb9eba_geom_idx on contour_cb9eba a  (cost=0.14..0.41 rows=1 width=746174)
        Index Cond: (b.geom && geom)
        Filter: _st_intersects(b.geom, geom)

analiza wyjaśniająca znajduje się poniżej:

Nested Loop  (cost=0.14..665.47 rows=37 width=44) (actual time=245.343..4629.091 rows=23 loops=1)
  ->  Seq Scan on v_line b  (cost=0.00..23.60 rows=1360 width=32) (actual time=0.011..0.013 rows=1 loops=1)
  ->  Index Scan using contour_cb9eba_geom_idx on contour_cb9eba a  (cost=0.14..0.41 rows=1 width=746174) (actual time=114.466..803.730 rows=23 loops=1)
        Index Cond: (b.geom && geom)
        Filter: _st_intersects(b.geom, geom)
        Rows Removed by Filter: 40
Planning time: 0.235 ms
Execution time: 4629.272 ms

Tabela konturów ma tylko 82 wiersze, ale z wieloma wierzchołkami do prawie 80000. Czy istnieje sposób, aby przyspieszyć ST_Intersection?

Odpowiedzi

1 dr_jts Sep 25 2020 at 11:59

Czy możesz podzielić linie konturowe na mniejsze, zawierające te same informacje o atrybutach? Wtedy indeks przestrzenny będzie bardziej efektywny.

To jest ten sam pomysł, co w ST_Subdivideprzypadku wielokątów. Byłoby miło, gdyby istniała analogiczna funkcja dla linii, ale dość łatwo jest napisać SQL, aby to zrobić.