Обикновено най-бързо, ако извлечете всички или повечето редове :
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;
Индексите тук нямат значение, пълното сканиране на таблици ще бъде най-бързо. Освен ако живите домашни любимци са рядкост case, след това частичен индекс трябва да помогне. Като:
CREATE INDEX pets_alive_idx ON pets (person_id, kind) WHERE alive;
Включих всички колони, необходими за заявката (person_id, kind)
за да разрешите сканиране само на индекс.
Обикновено най-бързо за малък поднабор или единичен ред :
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;
Трябва поне да имате индекс на pets.person_id
за това (или частичния индекс от по-горе) - и евентуално повече, в зависимост от WHERE
състояние.
Свързани отговори:
- Заявка с LEFT JOIN не връща редове за брой 0
- GROUP или DISTINCT след JOIN връща дубликати
- Получаване на брой на външен ключ от множество таблици