Vanligtvis snabbast om du hämtar alla eller de flesta rader :
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;
Index är irrelevanta här, genomsökningar av hela tabeller kommer att vara snabbast. Utom om levande husdjur är sällsynt fall, sedan ett partiellt index borde hjälpa. Gilla:
CREATE INDEX pets_alive_idx ON pets (person_id, kind) WHERE alive;
Jag inkluderade alla kolumner som behövs för frågan (person_id, kind)
för att tillåta endast index-skanningar.
Vanligtvis snabbast för en liten delmängd eller en enda rad :
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 åtminstone ha ett index på pets.person_id
för detta (eller det partiella indexet från ovan) - och möjligen mer, beroende på WHERE
skick.
Relaterade svar:
- Fråga med LEFT JOIN returnerar inte rader för antalet 0
- GROUP or DISTINCT after JOIN returnerar dubbletter
- Få räkning av främmande nyckel från flera tabeller