Integrovat dotaz
Vylepšením logiky na několika místech můžete celou operaci integrovat do jediného dotazu. Zabalení do funkce SQL je volitelné:
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;
Načte všechny element_id
pro stejné a podřízené místní obyvatele daného action_id
.
Volejte:
SELECT * FROM f_elem(3);
element_id
-----------
6
7
db<>fiddle zde
STARÝ sqlfiddle
To by mělo být podstatně již z několika důvodů rychleji. Nejviditelnější z nich jsou:
- Nahraďte pomalou smyčku v plpgsql čistým SQL.
- Zúžit počáteční sadu rekurzivního dotazu.
- Odstraňte nepotřebné a notoricky pomalé
IN
postavit.
Volám pomocí SELECT * FROM ...
místo pouhého SELECT
, i když má řádek pouze jeden sloupec, získáte název sloupce OUT
parametr (element_id
) Deklaroval jsem v hlavičce funkce.
Ještě rychlejší
Indexy
Index na action.action_id
je poskytován primárním klíčem.
Ale možná jste přehlédli index na local.parent_id
. Udělejte z toho obsahující vícesloupcový index (Postgres 9.2+) s parent_id
jako první prvek a local_id
jako druhý. To by mělo hodně pomoci, pokud tabulka local
je velký. Na malý stůl ne tolik nebo vůbec ne:
CREATE INDEX l_mult_idx ON local(parent_id, local_id);
Proč? Viz:
Nakonec vícesloupcový index
na tabulce element
by měl ještě pomoci:
CREATE INDEX e_mult_idx ON element (category_id, local_id, element_id);
Třetí sloupec element_id
je užitečné pouze k tomu, aby se z něj stal krycí index . Pokud váš dotaz načte více sloupců z tabulky element
, možná budete chtít přidat další sloupce do indexu nebo vypustit element_id
. Obojí to urychlí.
Materializované zobrazení
Pokud vaše tabulky dostávají málo nebo žádné aktualizace, materializovaný pohled poskytující předem vypočítanou sadu všech párů (action_id, element_id)
sdílením stejné kategorie by to bylo rychlé zesvětlení . Vytvořte (action_id, element_id)
(v tomto pořadí) primární klíč.