In der Regel am schnellsten, wenn Sie alle oder die meisten Zeilen abrufen :
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;
Indizes sind hier irrelevant, Full-Table-Scans sind am schnellsten. Außer lebende Haustiere sind selten Fall, dann ein Teilindex sollte helfen. Wie:
CREATE INDEX pets_alive_idx ON pets (person_id, kind) WHERE alive;
Ich habe alle Spalten eingefügt, die für die Abfrage (person_id, kind)
benötigt werden Nur-Index-Scans zuzulassen.
In der Regel am schnellsten für eine kleine Teilmenge oder eine einzelne Zeile :
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;
Sie sollten zumindest einen Index für pets.person_id
haben dafür (oder den Teilindex von oben) - und möglicherweise mehr, abhängig vom WHERE
Zustand.
Verwandte Antworten:
- Abfrage mit LEFT JOIN gibt keine Zeilen für die Anzahl 0 zurück
- GROUP oder DISTINCT nach JOIN gibt Duplikate zurück
- Zählen des Fremdschlüssels aus mehreren Tabellen