【问题标题】:How to improve this chain of SELECT queries?如何改进这个 SELECT 查询链?
【发布时间】:2020-05-26 21:09:40
【问题描述】:

我有这个功能查询,它在与主表中的多边形相交的参考表中构建多边形的加权平均值。

有没有比一组嵌套选择更好的方法来构建查询?在性能和可读性方面。我考虑过使用一系列临时表,但这似乎会更复杂而不是更少。

UPDATE tmp_master_geom AS master
SET weighted_value = sub_query.weighted_average
FROM
    -- calc weighted average column
    (SELECT
        the_id,
        (weighted_sum / total_area) AS weighted_average
        -- the_whole_intersection AS geom
    FROM
         -- group intersection pieces by original id
        (SELECT
            the_id,
            st_union(the_intersection) AS the_whole_intersection,
            SUM(the_area) AS total_area,
            SUM(the_area * ref_value) AS weighted_sum
        FROM
            -- get all intersections between master and reference
            (SELECT
                tmg.ID AS the_id,
                st_astext(trgl.geom) AS the_original,
                st_astext(st_intersection(tmg.geom, trgl.geom)) AS the_intersection,
                st_area(st_intersection(tmg.geom, trgl.geom)) AS the_area,
                trgl.ref_value AS ref_value
            FROM
                tmp_master_geom tmg,
                tmp_ref_geoms_larger trgl
            where st_intersects(tmg.geom, trgl.geom)
        ) AS intersection_table
    GROUP BY 
          the_id
    ) AS sum_table
    ) AS sub_query
WHERE
    master.id = sub_query.the_id
;

我的下一步是将其从查询转换为可重用函数,因此特别感谢考虑到这一点的建议。

【问题讨论】:

  • 您可以考虑使用公用表表达式 (CTE) 使其看起来更好,但我发现此查询目前相当可读。
  • CTE 是 Postgress 中的优化栅栏。除非您知道自己在做什么,否则不要使用它们,否则可能会对性能产生负面影响。

标签: sql postgresql postgis


【解决方案1】:

有没有比一组嵌套选择更好的方法来构建查询?在性能和可读性方面。

如果您担心代码的可读性,我会说您无需担心。但是,如果您主要关心的是性能,您可能需要EXPLAIN 您的查询来识别可能的瓶颈。

我考虑过使用一系列临时表,但这似乎会更复杂而不是更少。

根据结果集的大小,临时表可能会为您的代码增加一些性能!如果您正在处理非常大的表,那么创建一个临时表并对您正在搜索的列进行索引可能比查询子选择或 CTE 更快。

我的下一步是将其从查询转换为可重用函数,因此特别感谢考虑到这一点的建议。

如果你打算把整个东西打包成一个函数,你可以使用这个结构:

CREATE OR REPLACE FUNCTION gimme_the_geom() 
RETURNS GEOMETRY AS $BODY$
DECLARE geom GEOMETRY;
BEGIN
--your huge query goes here + INTO geom;
SELECT 'POINT(1 2)'::GEOMETRY INTO geom; 
RETURN geom; 
END;
$BODY$
LANGUAGE plpgsql;

用法

SELECT gimme_the_geom();

               gimme_the_geom               
--------------------------------------------
 0101000000000000000000F03F0000000000000040
(1 Zeile)

【讨论】:

    猜你喜欢
    • 2013-07-21
    • 2019-11-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-23
    • 2018-07-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多