Difference between Includes and Joins in Rails

Tram Ho

When you are starting to learn Rails, have you ever wondered about using includes or joins, because both are used in almost the same situation. includes uses eager loading while links use lazy loading. Both are used when certain operations are performed on related tables. And here is the difference. What’s the problem with joins?

Difference between eager loading and lazy loading

  • Eager Loading One way to improve performance is to cut down on the number of SQL queries. You can do this through eager loading.

When you run the above function, if you check the log on the server you will see that it generates 2 queries:

  1. First query to get all users
  2. The second query to get the friends of the users above
  • Lazy Loading

Same as the example in eager loading but get the data by lazy loading When you run the above function, if you check the log on the server you will see that it generates many queries:

  1. First query to get all users
  2. And then n number of queries are generated according to the number of friends of each user as it will loop through the user object.

Joins

Joins uses lazy loading so you also see what the problem is with joins

Here, we have retrieved the User in the first line and the data is added in each do loop. Here’s the interesting thing, to retrieve user.account.name, each time the database is called a query is generated. Meaning, if there are 10k Users then 10k separate queries will be fired. And this will make the system overkill when it comes to scaling. Is there no efficient way? Yes, it is Includes.

Includes

In rails docs it clearly says – “With Includes, Active Record ensures that all specified links are loaded using the minimum number of queries possible”. When we need data to be used from linked tables, must use Includes.

Here, the data from the accounts in the lookup table is loaded in the first line, because it says includes accounts. No additional queries are fired from the do loop for ‘user.account.name‘. Size of User table doesn’t matter now

It saves a lot of time. And it is proven to be very effective, when the application contains huge data. So Includes always takes precedence over Joins? Not really, there are some cases when includes doesn’t effectively exceed joins.

Here, we have used the User and Account tables, but the account has filter conditions. And then I used the data from the account table. So there is no need to carry data from accounts with users. This is why joins works in this case.

References

Share the news now