Thường nhanh nhất nếu bạn tìm nạp tất cả hoặc hầu hết các hàng :
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;
Các chỉ mục không liên quan ở đây, quét toàn bộ bảng sẽ nhanh nhất. Ngoại trừ nếu vật nuôi còn sống là một hiếm sau đó là chỉ mục một phần nên giúp. Như:
CREATE INDEX pets_alive_idx ON pets (person_id, kind) WHERE alive;
Tôi đã bao gồm tất cả các cột cần thiết cho truy vấn (person_id, kind)
để cho phép quét chỉ theo chỉ mục.
Thường nhanh nhất đối với tập hợp con nhỏ hoặc một hàng duy nhất :
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;
Ít nhất bạn phải có một chỉ mục trên pets.person_id
cho điều này (hoặc chỉ mục một phần từ phía trên) - và có thể nhiều hơn, tùy thuộc vào WHERE
điều kiện.
Các câu trả lời liên quan:
- Truy vấn với LEFT JOIN không trả về các hàng có số lượng là 0
- GROUP hoặc DISTINCT sau JOIN trả về các bản sao
- Nhận số lượng khóa ngoại từ nhiều bảng