Интегриране на заявка
Подобрявайки логиката на няколко места, можете да интегрирате цялата операция в една заявка. Обвиването в SQL функция не е задължително:
CREATE OR REPLACE FUNCTION f_elems(_action_id integer)
RETURNS SETOF integer AS
$func$
WITH RECURSIVE l AS (
SELECT a.category_id, l.local_id
FROM action a
JOIN local l USING (local_id)
WHERE a.action_id = $1
UNION ALL
SELECT l.category_id, c.local_id
FROM l
JOIN local c ON c.parent_id = l.local_id -- c for "child"
)
SELECT e.element_id
FROM l
JOIN element e USING (category_id, local_id);
$func$ LANGUAGE sql STABLE;
Извлича всички element_id
за същите и дъщерни локали на даден action_id
.
Обаждане:
SELECT * FROM f_elem(3);
element_id
-----------
6
7
db<>fiddle тук
СТАРИ sqlfiddle
Това трябва да е значително вече по-бързо поради няколко причини. Най-очевидните от тях са:
- Заместете чист SQL за бавен цикъл в plpgsql.
- Ограничете началния набор от рекурсивната заявка.
- Премахнете ненужното и известно бавно
IN
конструирам.
Обаждам се с SELECT * FROM ...
вместо само SELECT
, въпреки че редът има само една колона, за да получите името на колоната на OUT
параметър (element_id
) Декларирах в заглавката на функцията.
По-бързо, но
Индекси
Индекс на action.action_id
се предоставя от първичния ключ.
Но може да сте пропуснали индекса на local.parent_id
. Докато го правите, направете го покриващ многоколонен индекс (Postgres 9.2+) с parent_id
като първи елемент и local_id
като втори. Това трябва да помогне много, ако таблицата local
е голямо. Не толкова или изобщо не за малка маса:
CREATE INDEX l_mult_idx ON local(parent_id, local_id);
Защо? Вижте:
И накрая, индекс с няколко колони
на таблица element
трябва да помогне още:
CREATE INDEX e_mult_idx ON element (category_id, local_id, element_id);
Третата колона element_id
е полезен само за превръщането му в покриващ индекс . Ако вашата заявка извлече повече колони от таблицата element
, може да искате да добавите още колони към индекса или да премахнете element_id
. И двете ще го направят по-бързо.
Материализиран изглед
Ако вашите таблици получават малко или никакви актуализации, материализиран изглед, предоставящ предварително изчислен набор от всички двойки (action_id, element_id)
споделянето на същата категория би направило това светкавично бързо . Направете (action_id, element_id)
(в този ред) първичния ключ.