Généralement plus rapide si vous récupérez toutes ou la plupart des lignes :
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;
Les index ne sont pas pertinents ici, les analyses complètes de la table seront les plus rapides. Sauf si les animaux de compagnie vivants sont rares cas, puis un index partiel devrait aider. Comme :
CREATE INDEX pets_alive_idx ON pets (person_id, kind) WHERE alive;
J'ai inclus toutes les colonnes nécessaires pour la requête (person_id, kind)
pour autoriser les analyses d'index uniquement.
Généralement plus rapide pour un petit sous-ensemble ou une seule ligne :
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;
Vous devriez au moins avoir un index sur pets.person_id
pour cela (ou l'index partiel ci-dessus) - et peut-être plus, selon le WHERE
état.
Réponses associées :
- Requête avec LEFT JOIN ne renvoie pas de lignes pour un nombre de 0
- GROUP ou DISTINCT après JOIN renvoie des doublons
- Obtenir le nombre de clé étrangère de plusieurs tables