我有一个2900万行的大型PostgreSQL表。大小(根据pgAdmin中的stats选项卡几乎为9GB。)该表是使用空几何列启用后续gis的。
我想使用ST_GeomFromText更新几何列,读取存储在同一个表中的X和Y坐标列(SRID:27700)。但是,一次在整个表上运行此查询会导致“磁盘空间不足”和“连接到服务器丢失”错误......后者不太常见。
为了解决这个问题,我应该批量/阶段更新2900万行吗?我怎么能做100万行(第一个100万行),然后做下一百万行直到我达到2900万行?
或者还有其他更有效的方法来更新像这样的大表吗?
我应该补充一下,该表托管在AWS中。
我的UPDATE查询是:
UPDATE schema.table
SET geom = ST_GeomFromText('POINT(' || eastingcolumn || ' ' || northingcolumn || ')',27700);
您没有提供任何服务器规格,在最近的硬件上编写9GB可以非常快。
你可以使用一个很长的更新 - 除非你有对这个表的并发写入。
解决此问题的常见技巧(非常长的事务,锁定对表的写入)是将UPDATE拆分为基于主键的范围,在单独的事务中运行。
/* Use PK or any attribute with a known distribution pattern */
UPDATE schema.table SET ... WHERE id BETWEEN 0 AND 1000000;
UPDATE schema.table SET ... WHERE id BETWEEN 1000001 AND 2000000;
对于高级别的并发写入,人们使用更微妙的技巧(例如:SELECT FOR UPDATE / NOWAIT,轻量级锁,重试逻辑等)。
从我原来的问题:
但是,一次在整个表上运行此查询会导致“磁盘空间不足”和“连接到服务器丢失”错误......后者不太常见。
原来我们的亚马逊AWS实例数据库空间不足,阻止我原来的ST_GeomFromText查询完成。释放空间修复它。
重要的是,正如@mlinth所建议的那样,ST_Point比ST_GeomFromText运行我的查询要快得多(24分钟对2小时)。
我的最终查询是:
UPDATE schema.tablename
SET geom = ST_SetSRID(ST_Point(eastingcolumn,northingcolumn),27700);