Как улучшить эту цепочку запросов SELECT? - PullRequest
3 голосов
/ 27 мая 2020

У меня есть этот действующий запрос, который строит средневзвешенное значение многоугольников в справочной таблице, которые пересекают многоугольники в основной таблице.

Есть ли лучший способ структурировать запрос, чем набор вложенных выборок? И по производительности, и по удобочитаемости. Я рассматривал возможность использования ряда временных таблиц, но мне кажется, что это будет сложнее, чем меньше.

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
;

Мой следующий шаг - преобразовать это из запроса в функцию многократного использования, поэтому предложения с учетом этого особенно ценятся.

1 Ответ

3 голосов
/ 27 мая 2020

Есть ли лучший способ структурировать запрос, чем набор вложенных выборок? И по производительности, и по удобочитаемости.

Если вас беспокоит читабельность вашего кода, я бы сказал, что вам не о чем беспокоиться. Но если ваша главная забота - производительность, вы можете 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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...