简体   繁体   中英

How can I improve the performance of my sub-query?

I'm having problems with performance with IN queries in MYSQL.

Basically I'm building a friends graph, and when a user ~< 5 friends, it slows to crawl

however for users with high friends (7000+) - it runs super faster.

Here is my mock-up-query:

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

For some reason if the user_id has < 5 friends, the query takes 15s to return 0 entries.

On the friends table, I have an index on user_id and approved. On the activity entry I have an index on created_at.

Any suggestions or re-factoring?

Basically the subquery in your example will be executed per each row selected from activity table, you can reduce it by moving filter on activity table to the outer scope, so try to make your top-level query to be more specific in terms of filtering.

Try out INNER JOIN , does it work faster?

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 

Few questions:

  • Both tables has a user_id column?
  • approved column in the friends table?

Would this

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

accomplish the same. And is it any quicker?

I think you will need an index on friend_id,user_id, approved for the friends table.

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

Basically, IN's are kind of unpredictable, I like to use JOINs whenever possible.

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

Have an index on each: a.user_id , f.friend_id and f.user_id .

Do NOT index f.approved since it is very likely low cardinality column.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM