Về mặt hiệu suất, những truy vấn phụ tương quan đó có thể ăn bữa trưa của bạn. Và ngấu nghiến cả hộp ăn trưa của bạn, đối với các bộ lớn, vì cách MySQL xử lý chúng. Mỗi truy vấn con đó được thực thi cho mọi hàng được trả về trong truy vấn bên ngoài. Và điều đó có thể rất đắt đối với các bộ lớn.
Một cách tiếp cận thay thế là sử dụng chế độ xem nội tuyến để hiện thực hóa lượt thích và lượt không thích cho tất cả nội dung, sau đó thực hiện thao tác kết hợp với nội dung đó.
Tuy nhiên, cách tiếp cận này cũng có thể tốn kém, đặc biệt là khi bạn chỉ cần "đếm" phiếu bầu cho chỉ một vài hàng nội dung, trong số bazi tỷ hàng. Thông thường, có một vị từ từ truy vấn bên ngoài cũng có thể được kết hợp vào dạng xem nội tuyến, để giới hạn số hàng cần được kiểm tra và trả về.
Chúng tôi muốn sử dụng một phép nối OUTER cho dạng xem nội tuyến đó, vì vậy nó trả về một kết quả tương đương với truy vấn của bạn; trả về một hàng từ content
khi không có hàng nào phù hợp trong vote
bảng.
SELECT [... BUNCH OF FIELDS ...]
, COALESCE(v.likes,0) AS likes
, COALESCE(v.dislikes,0) AS dislikes
, COALESCE(v.myvote,'.Constants::NO_VOTE.') AS myvote
FROM content c
LEFT
JOIN ( SELECT vt.cId
, SUM(vt.vote = '.Constants::LIKE.') AS likes
, SUM(vt.vote = '.Constants::DISLIKE.') AS dislikes
, MAX(IF(vt.userId = '.USER_ID.',vt.vote,NULL)) AS myvote
FROM votes vt
GROUP
BY vt.cId
) v
ON v.cId = c.contentId
[... OTHER STUFF ... ]
Lưu ý rằng truy vấn chế độ xem nội tuyến (bí danh là v
) sẽ xem xét MỌI hàng đơn từ vote
bàn. Nếu bạn chỉ cần một tập hợp con, thì hãy cân nhắc việc thêm một vị từ thích hợp (trong mệnh đề WHERE hoặc dưới dạng JOIN vào một bảng khác). Không có dấu hiệu nào từ [... OTHER STUFF ...]
trong truy vấn của bạn cho dù nó chỉ trả về một vài hàng từ content
hoặc nếu bạn đang cần tất cả các hàng vì bạn đang sắp xếp theo likes
, v.v.
Đối với một số lượng nhỏ các hàng được chọn từ content
bảng, bằng cách sử dụng các truy vấn con tương quan (như trong truy vấn của bạn) thực sự có thể nhanh hơn so với việc hiện thực hóa một chế độ xem nội tuyến khổng lồ và thực hiện thao tác kết hợp với nó.
Ồ ... và đối với cả hai truy vấn, không cần phải nói rằng một chỉ mục thích hợp trên vote
bảng có cột ở đầu là cId
sẽ có lợi cho hiệu suất. Đối với dạng xem nội tuyến, bạn không muốn chi phí của MySQL phải thực hiện filesort
hoạt động trên tất cả các hàng đó để thực hiện GROUP BY. Và đối với các truy vấn con có tương quan, bạn muốn chúng sử dụng quét phạm vi chỉ mục, không phải quét toàn bộ.