s-espinosa / demonight

0 stars 3 forks source link

Reduce number of queries #170

Open s-espinosa opened 7 years ago

s-espinosa commented 7 years ago

@notmarkmiranda Can you take a look at this? Believe it reduces the number of queries run in this method.

Summary

Believe this change reduces the number of queries used to get eligible projects without a vote from a user. Takes advantage of the voted_projects relationship on User.

Details

Previously we had this:

projects = Vote.where(user_id: user_id).pluck(:project_id)
eligible = ["BE Mod 3", "FE Mod 3", "BE Mod 4", "FE Mod 4"]
where.not(id: projects).where(project_type: eligible)

Which results in two queries (one when we set projects, and the other beginning with where on the third line.

Updated to the following:

eligible = ["BE Mod 3", "FE Mod 3", "BE Mod 4", "FE Mod 4"]
where.not(
  id: User.find(user_id)
    .voted_projects
    .pluck(:id)
).where(project_type: eligible)

Finding the user and then finding that user's voted projects (rather than finding a value on the join given the user_id) seems to more directly reflect what this query is trying to do.

Thought this would still run two queries, but when I run #to_sql on that method it results in a single query with a subquery in it to find the voted projects. That feels like a win to me. Can you confirm?

Questions

  1. Believe we sacrifice some legibility here for fewer queries. Is it worth it?

  2. I'm frustrated that the following doesn't work, and can't spot what I'm missing. Tried this with a .find in place of the .where as well:

eligible = ["BE Mod 3", "FE Mod 3", "BE Mod 4", "FE Mod 4"]
where.not(
  User.find(user_id)
    .voted_projects
).where(project_type: eligible)

Might not chase this too much if the updated query in the current PR results in a single query.