PostGIS медленный ST_Intersection

Sep 25 2020

Я пытаюсь получить пересечения между одной прямой и некоторыми контурными линиями. Используя приведенный ниже 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);

Но на выполнение запроса уходит десятки секунд. Настроил postgresql, не помогает. Я создал индекс по таблице контуров, не помогает. Объяснение ниже:

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)

объяснение анализа приведено ниже:

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

В таблице контуров всего 82 строки, но с количеством вершин почти до 80000. Есть ли способ сделать ST_Intersection быстрее?

Ответы

1 dr_jts Sep 25 2020 at 11:59

Можете ли вы разделить контурные линии на более мелкие линии с одинаковой атрибутивной информацией? Тогда пространственный индекс будет более эффективным.

Это та же идея, что и ST_Subdivideдля полигонов. Было бы неплохо, если бы существовала аналогичная функция для строк, но для этого довольно легко написать SQL.