如何提高子查询的性能?

时间:2011-08-10 14:47:43

标签: mysql sql indexing

我在使用MYSQL中的IN查询时遇到了性能问题。

基本上我正在构建一个朋友图,当用户〜< 5个朋友,它爬得慢“

然而对于拥有高朋友(7000+)的用户来说,它的运行速度更快。

这是我的模拟查询:

SELECT *
FROM activity
WHERE user_id IN 
(
   SELECT friend_id
   FROM friends
   WHERE user_id = 1 and approved = 1
)
order by activity.created_at DESC
LIMIT 25

出于某种原因,如果user_id具有< 5位朋友,查询需要15秒才能返回0个条目。

在friends表上,我有一个user_id的索引并已批准。在活动条目上,我有一个关于created_at的索引。

有任何建议或重新考虑吗?

4 个答案:

答案 0 :(得分:1)

基本上,您的示例中的子查询将按照从activity表中选择的每一行执行,您可以通过将activity表上的过滤器移动到外部范围来减少它,因此请尝试使用级别查询在过滤方面更具体。

试用INNER JOIN,它能更快地运作吗?

SELECT * FROM activity a
INNER JOIN friends f ON a.user_id = f.friend_id
WHERE a.user_id = 1 AND f.approved = 1
order by activity.created_at DESC LIMIT 25 

几个问题:

  • 两个表都有一个user_id列?
  • 朋友表中的已批准列?

答案 1 :(得分:0)

这会是

吗?

SELECT * FROM activity t1 join friends t2 where t1.user_id=t2.friends_id and t2.user_id=1 and t2.approved=1 order by activity.created_at DESC LIMIT 25

完成同样的事情。它更快吗?

我认为你需要一个关于friend_id,user_id的索引,已经批准用于好友表。

答案 2 :(得分:0)

Select * 
FROM activity a
JOIN (Select * from friends WHERE user_id = 1 and approved = 1) f
ON a.user_id = f.friend_id
ORDER BY a.created_at DESC
LIMIT 25

基本上,IN有点不可预测,我喜欢尽可能使用JOIN。

答案 3 :(得分:0)

SELECT a.* FROM activity a, friends f
WHERE 
           a.user_id = f.friend_id
    AND    f.user_id = 1 
    AND    f.approved = 1
ORDER BY activity.created_at DESC 
LIMIT 25

每个都有一个索引:a.user_idf.friend_idf.user_id

不要将f.approved编入索引,因为它很可能是低基数列。

相关问题