为什么这个 PostGIS 查询需要这么长时间才能运行?

PyM*_*apr 2 postgresql performance postgis postgresql-performance

我一般是 PostGIS 和 SQL 的新手。我正在对多边形运行查询,我希望它只选择不同的几何图形,然后修复 ( ST_MakeValid()) 那些不同的几何图形。从而在修复无效几何图形的过程中删除重复的几何图形。但是,查询需要很长时间才能运行(几天)。这是 SQL 语句:

CREATE TABLE schema.table_geomfix AS 
SELECT gid,id, ST_MakeValid(geom) as geom 
FROM schema.table_polygons 
WHERE geom IN (SELECT DISTINCT geom FROM schema.table_polygons);
Run Code Online (Sandbox Code Playgroud)

分别运行两个 select 语句很快。大约 1 分钟makevaliddistinct陈述和 15 秒的陈述。

  1. 为什么运行组合语句需要这么长时间?
  2. 关于改进查询以使其更快的任何建议?

注意:geom列上有一个索引。

Erw*_*ter 5

您的查询是不必要的复杂,可以解开到这个 100% 等价的查询:

SELECT gid, id, ST_MakeValid(geom) AS geom
FROM   schema.table_polygons
WHERE  geom IS NOT NULL;
Run Code Online (Sandbox Code Playgroud)

original 和 this one 都没有删除任何重复项(除非可能删除了一些 with geom IS NULL,但我怀疑这是您的意图)。

可能的误会

关于子句中的输出列名称有一个常见的误解WHERE- 您只能引用输入列名称。所以,geom在:

WHERE geom IN ...
Run Code Online (Sandbox Code Playgroud)

引用原始输入列而不是输出列( 的结果ST_MakeValid(geom))。

有关的:

如果您的实际意图是只保留结果ST_MakeValid(geom)等于任何当前现有geom条目的行:

SELECT gid, id, ST_MakeValid(t.geom) AS geom 
FROM   schema.table_polygons t
WHERE  EXISTS (
   SELECT 1
   FROM   schema.table_polygons
   WHERE  geom = ST_MakeValid(t.geom)
   );
Run Code Online (Sandbox Code Playgroud)

我添加了一个表别名和表限定来阐明什么是什么。

您提到的索引只会对这个变体有所帮助。

如果您的实际意图是在修复geom值后合并重复的行:

SELECT DISTINCT ON (ST_MakeValid(t.geom))
       gid, id, ST_MakeValid(geom) AS geom 
FROM   schema.table_polygons t
ORDER  BY ST_MakeValid(t.geom), gid, id;
Run Code Online (Sandbox Code Playgroud)

您没有定义如何打破平局以及从一组欺骗中保留哪一行。我保留gid每组中最小的那一行。和id剩下的骗子中最小的。细节:

旁白:将模式称为“模式”就像将您的儿子命名为“儿子”并希望不再有儿子到达。换句话说:不要。

  • 这就是为什么“肖恩”康纳利将他的儿子命名为“杰森”而不仅仅是“儿子”;) (4认同)