Normalmente mais rápido se você buscar todas ou a maioria das linhas :
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;
Índices são irrelevantes aqui, varreduras completas de tabela serão mais rápidas. Exceto se animais de estimação vivos são raros caso, então um índice parcial deve ajudar. Curti:
CREATE INDEX pets_alive_idx ON pets (person_id, kind) WHERE alive;
Incluí todas as colunas necessárias para a consulta
(person_id, kind)
para permitir varreduras somente de índice. SQL Fiddle.
Normalmente mais rápido para um pequeno subconjunto ou uma única linha :
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;
Você deve ter pelo menos um índice em
pets.person_id
para isso (ou o índice parcial acima) - e possivelmente mais, dependendo do WHERE
doença. Respostas relacionadas:
- Consulte com LEFT JOIN não retornando linhas para contagem de 0
- GROUP ou DISTINCT depois JOIN retorna duplicatas
- Obter contagem de chave estrangeira de várias tabelas