如何优化SQL查询的速度

时间:2015-07-27 08:57:08

标签: mysql

我理解这个查询中的主要问题是两个嵌入式子查询,这将返回每行返回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

任何优化提示将不胜感激。我不仅仅想要“这是解决问题的答案”,因为我希望将来可以自己做出这些优化,解释为什么它更快以及解决方案如何到达将更有利于我

0 个答案:

没有答案