Typisk hurtigst, hvis du henter alle eller de fleste rækker :
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;
Indekser er irrelevante her, fuld tabelscanninger vil være hurtigst. Undtagen hvis levende kæledyr er sjældent case, derefter et delvist indeks skulle hjælpe. Ligesom:
CREATE INDEX pets_alive_idx ON pets (person_id, kind) WHERE alive;
Jeg inkluderede alle kolonner, der var nødvendige for forespørgslen (person_id, kind)
for at tillade kun indeksscanninger.
Typisk hurtigst for en lille undergruppe eller en enkelt række :
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;
Du bør i det mindste have et indeks på pets.person_id
for dette (eller det delvise indeks fra oven) - og muligvis mere, afhængigt af WHERE
tilstand.
Relaterede svar:
- Forespørgsel med LEFT JOIN returnerer ikke rækker for optælling af 0
- GROUP or DISTINCT after JOIN returnerer dubletter
- Få optælling af fremmednøgle fra flere tabeller