Обновление таблицы postgis с подзапросом пространственного соединения - PullRequest
0 голосов
/ 06 сентября 2018

Я поддерживаю две таблицы postgis: "track_points" и "buffers". Таблица «track_point» содержит огромное количество (почти один миллиард) точек, а таблица «buffer» содержит около 20 полигонов.

Что я хочу сделать, так это проверить все точки, в которых они содержатся, и назначить соответствующий идентификатор буфера для записи точек. После поиска в Интернете я обнаружил, что "пространственные соединения" могут быть здесь очень полезны. Основываясь на том, что я нашел в Интернете, я собрал запрос, который выглядит следующим образом ({схема} - просто заполнитель для имени схемы):

WITH join_query AS (
  SELECT
    points.id AS point_id,
    buffers.profile_id AS profile_id
  FROM {schema}.buffers AS buffers
  JOIN {schema}.track_points AS points
  ON ST_Contains(buffers.geom, points.geom)
)

UPDATE {schema}.track_points
  SET profile_id = join_query.profile_id
  FROM join_query
  WHERE id = join_query.point_id

Я выполнил запрос, но ни одно из значений profile_id в таблице track_points не изменилось. Я думаю, что-то не так с моим запросом?! ??

Кроме того, есть ли у кого-нибудь совет, как более эффективно достичь моей цели (учитывая огромное количество баллов в таблице track_points)?

Кстати, я использую psycopg2 Python для подключения к базе данных.

1 Ответ

0 голосов
/ 06 сентября 2018

Если ваша таблица баллов содержит миллиард записей, даже не пытайтесь обновить ее - или вы можете, если вы можете подождать несколько дней / недель, чтобы закончить это обновление;). Для таких массовых операций идеальным решением является CTAS (создайте таблицу как select); Я предполагаю, что ваши полигоны не пересекаются друг с другом, если да, то скажите мне profile_id, какой буфер вы хотите (max, min ....);

create table track_points2 as
select your_columns_for_track_points(expect profile_id), b.profile_id 
  from track_points tp, buffers b
 where st_dwithin(tp.geom, b.geom,0);

Затем удалите существующую таблицу track_points и замените ее новой;

drop table track_points;
alter table track_points2 alter rename to track_points;

И создайте все необходимые индексы и ограничения для вашей новой таблицы.

Если вы не можете удалить таблицы, изменить таблицы и т. Д. В своей базе данных, то, конечно, вам придется обновить, но будьте готовы к долгому ожиданию.

 update track_points tp
    set profile_id=b.profile_id
   from buffers b
  where st_dwithin(tp.geom, b.geom,0);

Как я уже писал ранее, если у вас есть пересекающиеся буферы / полигоны, вам придется изменить обновление, чтобы получить то, что вы хотите, из множества вариантов profile_id.

...