Zintegruj zapytanie
Udoskonalając logikę w kilku miejscach, możesz zintegrować całą operację w jednym zapytaniu. Zawijanie w funkcję SQL jest opcjonalne:
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;
Pobiera wszystkie element_id
dla tego samego i podrzędnego lokalnego dla danego action_id
.
Zadzwoń:
SELECT * FROM f_elem(3);
element_id
-----------
6
7
db<>fiddle tutaj
STARY sqlfiddle
Powinno to być zasadniczo szybciej już z kilku powodów. Najbardziej oczywiste to:
- Zastąp czystym SQL wolnym zapętleniem w plpgsql.
- Zawęź początkowy zestaw zapytania rekurencyjnego.
- Usuń niepotrzebne i notorycznie wolne
IN
konstruować.
Dzwonię z SELECT * FROM ...
zamiast po prostu SELECT
, nawet jeśli wiersz ma tylko jedną kolumnę, aby uzyskać nazwę kolumny OUT
parametr (element_id
) Zadeklarowałem w nagłówku funkcji.
Szybciej, ale
Indeksy
Indeks na action.action_id
jest dostarczany przez klucz podstawowy.
Ale mogłeś przegapić indeks local.parent_id
. Będąc przy tym, postaraj się, aby pokrywał się wielokolumnowym indeksem (Postgres 9.2+) z parent_id
jako pierwszy element i local_id
jako drugi. Powinno to bardzo pomóc, jeśli tabela local
jest duży. Nie tak bardzo lub wcale na mały stolik:
CREATE INDEX l_mult_idx ON local(parent_id, local_id);
Czemu? Zobacz:
Wreszcie indeks wielokolumnowy
w tabeli element
powinien pomóc trochę więcej:
CREATE INDEX e_mult_idx ON element (category_id, local_id, element_id);
Trzecia kolumna element_id
przydaje się tylko, aby uczynić go indeksem obejmującym . Jeśli zapytanie pobierze więcej kolumn z tabeli element
, możesz dodać więcej kolumn do indeksu lub usunąć element_id
. Albo przyspieszy to.
Widok zmaterializowany
Jeśli Twoje tabele otrzymują niewiele aktualizacji lub nie otrzymują ich wcale, zmaterializowany widok dostarczający wstępnie obliczony zestaw wszystkich par (action_id, element_id)
udostępnienie tej samej kategorii sprawiłoby, że to szybkie rozjaśnianie . Utwórz (action_id, element_id)
(w tej kolejności) klucz podstawowy.