【问题标题】:Update postgis table with spatial join subquery使用空间连接子查询更新 postgis 表
【发布时间】:2018-09-06 12:08:28
【问题描述】:

我维护两个 postgis 表:“track_points”和“buffers”。 “track_point”表包含大量(近 10 亿个)点,“buffer”表包含大约 20 个多边形。

我想要做的是,检查包含它们的缓冲区中的所有点,并将相应的缓冲区 id 分配给点记录。在网上搜索后,我发现“空间关节”在这里可能有很大帮助。根据我在网上找到的内容,我整理了一个如下所示的查询({schema} 只是架构名称的占位符):

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

我运行了查询,但 track_points 表中的 profile_id 值都没有改变。所以我想我的查询一定有问题?!??

另外,是否有人建议如何更有效地实现我的目标(关于 track_points 表中的大量点)?

顺便说一下,我正在使用 Python 的 psycopg2 连接数据库。

【问题讨论】:

    标签: python postgis psycopg2


    【解决方案1】:

    如果您的点表有数十亿条记录,甚至不要尝试更新它 - 或者您可以等待几天/几周来结束此更新;)。对于这种大规模操作的完美解决方案是 CTAS(创建表作为选择); 我假设你的多边形不相交,如果是,那么告诉我 profile_id 你想要哪个缓冲区(最大,最小....);

    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 选择中获得您想要的。

    【讨论】:

    • 好的,我会试试你的建议。感谢您及时的回复!无论如何,您有什么理由使用 ST_DWithin 而不是 ST_Contains?两者都使用边界框检查,所以我认为它们应该具有相似的性能。
    • 我喜欢 st_dwithin() - 我不必关心里面有什么 ;) 当我必须找到里面或接触的东西时,我经常在查询中使用它,或者开始里面 。使用 st_dwithin 我可以一次找到所有这些,而不必使用 3 个不同的条件。但当然,在您的情况下,距离为 0 的点和多边形 st_dwithin() 在逻辑上等于 st_contains()。如果有帮助别忘了投票或接受:P
    • 所以我测试了两个查询:UPDATE 版本和 CTAS 版本。令人惊讶的是,两个版本花费的时间大致相同,大约 2 小时即可获得 1.4 亿点。由于我不必创建索引,因此更新版本甚至更快一点。无论如何,对于接下来的处理步骤,使用其中只有映射点的表格更容易,所以我决定使用 CTAS 版本!不过,我有点想知道为什么 UPDATE 版本如此“快”...
    • 从这 140M 更新了多少条记录。如果这低于 2%,那么更新可能会比 CTAS 更快。但我不相信如果你更新 140M 的大部分,CTAS 不会比正常更新快至少 10 倍。
    • 是的,这很有道理!只更新了大约 3-4% 的点数。
    猜你喜欢
    • 1970-01-01
    • 2020-08-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-02
    • 2023-01-18
    • 2014-01-27
    • 2020-05-31
    相关资源
    最近更新 更多