我理解这个查询中的主要问题是两个嵌入式子查询,这将返回每行返回2个额外查询,大大增加了大型结果集的执行复杂性。这个查询很好,但是现在我们接近2000个用户,其性能急剧下降,我已尽可能多地删除无关信息(主要是选择字段)。
SELECT
e.Entity_Id,
f.Category AS FC,
s.list_visibility,
p.Pref_Everyone
FROM
entity e
LEFT JOIN
setting s
ON
e.Entity_Id IN(s.Entity_Id)
AND (s.list_visibility = 1 OR s.list_visibility = NULL)
LEFT JOIN
preferences p
ON
e.Entity_Id IN(p.Entity_Id)
AND (p.Pref_Everyone = 1 OR p.Pref_Everyone = NULL)
LEFT
JOIN
friends f
ON
e.Entity_Id
IN (f.Entity_Id1, f.Entity_Id2)
-- Filter out existing friends
AND f.Category NOT IN (1, 2, 4)
WHERE e.Entity_Id != :user_id
AND TIMESTAMPDIFF(YEAR, e.DOB, CURDATE()) BETWEEN :lower AND :upper
-- First subquery to filter out people a friend request has been sent to
AND e.Entity_Id NOT IN
(
SELECT Req_Receiver FROM friend_requests WHERE Req_Sender = :user_id
UNION ALL
SELECT Req_Receiver FROM friend_requests WHERE Req_Sender = e.Entity_Id AND Req_Receiver = :user_id
)
-- Second subquery to filter out existing friends
-- (only check one way as I have added a reciprocal relationship
AND e.Entity_Id NOT IN
(
SELECT Entity_Id1 FROM friends WHERE Entity_Id2 = :user_id
)
-- Only get users within a 500km radius
AND (6371 * acos( cos( radians(:currLat) ) * cos( radians(e.Last_CheckIn_Lat) ) * cos( radians(e.Last_CheckIn_Long) - radians(:currLong) ) + sin( radians(:currLat) ) * sin( radians(e.Last_CheckIn_Lat) ) ) ) < 500
GROUP BY e.Entity_Id
LIMIT 50
任何优化提示将不胜感激。我不仅仅想要“这是解决问题的答案”,因为我希望将来可以自己做出这些优化,解释为什么它更快以及解决方案如何到达将更有利于我