Obvykle nejrychlejší, pokud načítáte všechny nebo většinu řádků :
SELECT pp.id
, COALESCE(pt.a_dog_ct, 0) AS alive_dogs_count
, COALESCE(pt.a_cat_ct, 0) AS alive_cats_count
FROM people pp
LEFT JOIN (
SELECT person_id
, count(kind = 'dog' OR NULL) AS a_dog_ct
, count(kind = 'cat' OR NULL) AS a_cat_ct
FROM pets
WHERE alive
GROUP BY 1
) pt ON pt.person_id = pp.id;
Indexy jsou zde irelevantní, úplné skenování tabulky bude nejrychlejší. Kromě pokud jsou živá domácí zvířata vzácná případ, pak částečný index by měl pomoci. Jako:
CREATE INDEX pets_alive_idx ON pets (person_id, kind) WHERE alive;
Zahrnul jsem všechny sloupce potřebné pro dotaz (person_id, kind)
abyste povolili skenování pouze s indexem.
Obvykle nejrychlejší pro malou podmnožinu nebo jeden řádek :
SELECT pp.id
, count(kind = 'dog' OR NULL) AS alive_dogs_count
, count(kind = 'cat' OR NULL) AS alive_cats_count
FROM people pp
LEFT JOIN pets pt ON pt.person_id = pp.id
AND pt.alive
WHERE <some condition to retrieve a small subset>
GROUP BY 1;
Měli byste mít alespoň index na pets.person_id
pro toto (nebo částečný index shora) - a možná i více, v závislosti na WHERE
podmínka.
Související odpovědi:
- Dotaz s LEFT JOIN nevrací řádky pro počet 0
- GROUP nebo DISTINCT po JOIN vrátí duplikáty
- Získat počet cizího klíče z více tabulek