Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails 3: Lazy loading versus eager loading

In Rails 3, are these the same, or different? How do they differ?

o = Appointment.find(297)
o.service


o = Appointment.includes(:service).find(297)
o.service
like image 312
99miles Avatar asked Oct 20 '10 06:10

99miles


People also ask

Which is better lazy loading or eager loading?

Eager Loading. Eager loading generates all web page content as soon as possible, while lazy loading delays the display of non-essential content.

When should you not use lazy loading?

Ultimately, lazyload should only be used to speed up page load or decrease server use. And NOT to compensate for poor web coding or underpowered web server. When used correctly, lazy load should have no visual impact on your web pages. Used incorrectly, lazy load affects user experience.

What is eager loading rails?

There are actually three ways to do eager loading in Rails. use preload() to fetch the data with a separate db query (just one though, avoiding N+1 queries) use eager_load() to fetch data with one large query and an outer join. use includes() to dynamically find the best solution and preload or eager load the data.

Is lazy loading better?

Today, lazy loading is widely used in web applications to improve application performance. It helps developers reduce loading times, optimize data usage and improve the user experience. However, overusing lazy loading can affect the application performance negatively.


1 Answers

I'm not sure, but it looks like you have belongs_to :serivce in the Appointment class and has_many :appointments the Service class. Correct?

In that case there won't be any difference between your 2 examples. Rails will execute 2 queries in both cases:

Appointment Load (0.0ms)  SELECT "appointments".* FROM "appointments" WHERE ("appointments"."id" = 1) LIMIT 1
Service Load (0.0ms)  SELECT "services".* FROM "services" WHERE ("services"."id" = 1) LIMIT 1

If, on the other hand, you were calling:

s = Service.find(123)

and then do something like:

s.appointments.find(1)
s.appointments.find(2)

etc. in many places in the code, then there would be as many queries to the database as the number of these calls (Rails 3 is pretty smart here, so if you executed s.appointments.each it would actually fetch all the appointments in 1 query).

In that case it'd be better to call:

s = Service.include(:appointments).find(123)

because then Rails will execute only 2 queries: one to fetch the Service and one to fetch all the appointments:

Service Load ( 0.0ms )  SELECT "services".* FROM "services" WHERE ("services"."i
d" = 123) LIMIT 1
Appointment Load ( 0.0ms )  SELECT "appointments".* FROM "appointments" WHERE ("
appointments".service_id = 123) 
like image 59
Matt Avatar answered Sep 20 '22 12:09

Matt