PostGIS lento ST_Intersection

Sep 25 2020

Estoy tratando de obtener intersecciones entre una línea recta y algunas curvas de nivel. Usando el SQL a continuación:

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);

Pero la consulta tarda decenas de segundos en finalizar. He ajustado el postgresql, no ayuda. He creado índice en la tabla de contorno, no ayuda. la explicación está a continuación:

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)

el análisis de explicación está a continuación:

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

La tabla de curvas de nivel tiene solo 82 filas pero con muchos vértices hasta casi 80000. ¿Hay alguna forma de hacer que ST_Intersection sea más rápido?

Respuestas

1 dr_jts Sep 25 2020 at 11:59

¿Puede dividir las curvas de nivel en líneas más pequeñas que lleven la misma información de atributos? Entonces el índice espacial será más efectivo.

Esta es la misma idea que se usa ST_Subdividepara polígonos. Sería bueno si hubiera una función análoga para las líneas, pero es bastante fácil escribir SQL para hacer esto.