2015-11-12 2 views
1

У меня есть 2.2M линии геометрии (дороги) в одном столе и 1500 линий геометрии (береговые линии) в другом. Обе таблицы имеют пространственный индекс. Мне нужно найти конечные точки дорог, которые находятся на определенном расстоянии от берега и хранить геометрию точки вместе с расстоянием. Текущее решение, которое кажется неэффективным, и занимает много часов, чтобы завершить работу на очень быстрой машине;Postgresql: Найти конечные точки дороги на расстоянии от берега

CREATE TEMP TABLE с начальными и конечными точками геометрии дороги на расстоянии, используя ST_STARTPOINT, ST_ENDPOINT и ST_DWITHIN. СОЗДАТЬ ПРОСТРАНСТВЕННЫЕ ИНДЕКСЫ для обоих столбцов геометрии в таблице темпа.

Выполняют две операции INSERT INTO, одну для начальной точки и одну для конечных точек; SELECT геометрия и расстояние, используя ST_DISTANCE от точки до береговой линии и WHERE ST_DWITHIN, чтобы рассматривать только точки на выбранном расстоянии.

код выглядит вдоль этих линий:

create temp table roadpoints_temp as select st_startpoint(road.geom) as geomstart, st_endpoint(road.geom) as geomend from 
    coastline_table coast, roadline_table road where st_dwithin(road.geom, coast.geom, 100); 

create index on roadpoints_temp (geomstart); 

create index on roadpoints_temp (geomend); 

create table roadcoast_points as select roadpoints_temp.geomstart as geom, round(cast(st_distance(roadpoints_temp.geomstart,kyst.geom) as numeric),2) as dist 
    from roadpoints_temp, coastline_table coast where st_dwithin(roadpoints_temp.geomstart, coast.geom, 100); 

insert into roadcoast_points select roadpoints_temp.geomend as geom, round(cast(st_distance(roadpoints_temp.geomend,kyst.geom) as numeric),2) as dist 
    from roadpoints_temp, coastline_table coast where st_dwithin(roadpoints_temp.geomend, coast.geom, 100); 

drop table roadpoints_temp; 

Все комментарии и предложения приветствуются :-)

+0

Попробуйте добавить 'USING gist' для индексов? http://www.postgresql.org/docs/9.3/interactive/sql-createindex.html – joop

+0

Я пробовал ваш код с некоторыми тестовыми данными, но не имел проблем с производительностью. У вас очень сложные геометрии? (со многими вершинами). Может быть, вы можете предоставить образец из ваших данных? –

+0

Я попытался явно использовать gist, но это не повлияло на производительность - создание временной таблицы, по-видимому, занимает большую часть времени обработки. – BobJohnson

ответ

0

Вы должны эффективно использовать свои индексы. Кажется, что самым быстрым планом было бы найти для каждого побережья все дороги, которые находятся на расстоянии от него. Выполнение двух повторных проверок по отдельности означает, что вы теряете соединение ближайшей береговой линии с дорогой и должны снова и снова находить эту пару.

Вам необходимо проверить свой план выполнения с помощью EXPLAIN, чтобы выполнить сканирование Seq на таблице береговой линии и сканирование индекса GiST на дорожном столе.

select road.* 
from coastline_table coast, roadline_table road 
where 
    ST_DWithin(coast.geom, road.geom, 100) -- indexed query  
    and -- non-indexed recheck 
    (
     ST_DWithin(ST_StartPoint(road.geom), coast.geom, 100) 
     or ST_DWithin(ST_EndPoint(road.geom), coast.geom, 100) 
    ); 
Смежные вопросы