非常多的SQL UNION SELECT语句超过了max_stack_depth

时间:2019-01-05 11:22:03

标签: sql postgresql postgis

我正在尝试为一组给定多边形中的一个或多个内的所有唯一点开发基于空间的SQL查询。我在具有6个vCPU和16 GB RAM的云VPS上使用PostGIS。有问题的空间测试是WHERE子句上的ST_Contains。多边形集大约有40,000种独特的几何形状,约束了370万个特征点数据集。

我的问题是,当我创建一个包含13,000多个多边形的查询(因此有13,000 SELECT语句)时,PostGIS服务器将以ERROR: stack depth limit exceeded"进行响应 HINT: Increase the configuration parameter "max_stack_depth"

我想知道为什么以及是否有解决方法。

这是优化练习的一部分。我已经将多边形几何作为单独的SELECT检索,以形成所需的SQL查询。我想执行将多边形集测试为单个SQL语句的查询。到目前为止,我一直在为每个多边形建立一个SELECT子查询,然后为每个多边形建立UNION作为起点。编译后,仅使用13,000个多边形的查询大约有28,000,000个字符,我相信这比PostGIS SQL语句的限制要少得多。

我尝试了较小的尺寸,发现在接近极限的情况下仍具有正常的性能。我早些时候达到了此限制,但是在收到错误消息的建议后,我将“ max_stack_depth”增加到近似“ ulimit -s”返回的大小。根据我目前的理解,此SQL语句不是任何一种递归函数,而我希望这会导致超出堆栈深度。

从我对堆栈与堆内存的了解中,我也无法理解为什么该查询会导致堆栈超载,因为大多数必需的存储数据都应该在堆中结束。我还希望查询在收集结果时按顺序执行,但似乎PostGIS可能先运行所有SELECT子语句,然后汇总结果。

我选择不尝试将各个多边形的几何形状合并为一个多边形,因为它们覆盖了非常不同的地理区域(即,没有聚集成一个简单的整体),我相信这将大大降低空间索引的优势。

我当前正在使用的SQL脚本遵循以下模式(已调整为适合本文):

SELECT * FROM point_table WHERE ST_Contains("poly1_geom_str", pt_geom_col)
UNION
SELECT * FROM point_table WHERE ST_Contains("poly2_geom_str", pt_geom_col)
UNION
....
SELECT * FROM point_table WHERE ST_Contains("polyN_geom_str", pt_geom_col);

我构造此SQL语句的策略不太可能解决吗?我可以尝试使用另一种策略来避免递归问题吗?

2 个答案:

答案 0 :(得分:2)

您可以尝试使用此查询变体。它根据不同的多边形字符串创建一个临时表,然后基于ST_Contains执行联接:

SELECT  DISTINCT point_table.* 
FROM    point_table 
JOIN    (values ("poly1_geom_str"), 
                ("poly2_geom_str")
        ) as polys(poly_str)
     ON ST_Contains(poly_str, pt_geom_col)

当然,如果这些几何图形实际上来自现有表,则只需联接该表:

SELECT  DISTINCT point_table.* 
FROM    point_table 
JOIN    polys
     ON ST_Contains(poly_str, pt_geom_col)

答案 1 :(得分:0)

您是否考虑过or

SELECT *
FROM point_table
WHERE ST_Contains("poly1_geom_str", pt_geom_col) OR
      ST_Contains("poly2_geom_str", pt_geom_col) OR
      ....
      ST_Contains("polyN_geom_str", pt_geom_col);