Por lo general, es más rápido si obtiene todas o la mayoría de las filas :
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;
Los índices son irrelevantes aquí, los escaneos completos de la tabla serán más rápidos. Excepto si las mascotas vivas son raras caso, entonces un índice parcial debería ayudar. Me gusta:
CREATE INDEX pets_alive_idx ON pets (person_id, kind) WHERE alive;
Incluí todas las columnas necesarias para la consulta (person_id, kind)
para permitir exploraciones de solo índice.
Por lo general, el más rápido para un pequeño subconjunto o una sola fila :
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;
Debería tener al menos un índice en pets.person_id
para esto (o el índice parcial de arriba) - y posiblemente más, dependiendo del WHERE
condición.
Respuestas relacionadas:
- Consulta con LEFT JOIN no devuelve filas para la cuenta de 0
- GRUPO o DISTINTO después JOIN devuelve duplicados
- Obtener recuento de clave externa de varias tablas