sql >> Databáze >  >> RDS >> PostgreSQL

Spojte dvě tabulky pomocí id a potomků ze stromové tabulky

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íč.




  1. přepište ?id=__ do názvu stránky uloženého v řádku db

  2. jak se zbavit síťové chyby (TCP_ERROR) v BIRT?

  3. SQL nevloží hodnoty null pomocí BULK INSERT

  4. Oracle na PostgreSQL — Kurzory a lstromy