On Sep 23, 9:58 pm, Fernando P. [email protected]
wrote:
The equivalent with :joins, only takes 0.004s of DB time.
Unfortunately, your findings is also misleading in a sense that your
associations are simplistic compared to mine.
- Fred mentioned that the bad case is orders having two has_manys,
which orders doesn’t. My depot model, on the other hand, has 3
has_manys.
- My reporting requirements are more intensive than yours.
- You didn’t even bother to post your :joins and :select construct.
The big advantage of :joins, is that I can use :select to only fetch the
rows I need, whereas with :include I need to retrieve all the fields.
The drawback of :joins, is that I don’t have objects with relationships
as one could expect with :include, but I consider that having objects is
overwhelming. The goal is to present retrieved data from the DB to the
user or to a reporting system, therefore objects are not that important.
Again, your model is too simplistic. Objects are going to be important
when you’re generating a report with a higher-degree of complexity to
what you’ve mentioned.
Anyway I would like to see Erol F. come with proof that :include
is faster than :joins.
Fair enough, here is my benchmark with the following dataset:
- 10 Depots
- 1000 Trucks per Depot
- 1000 Containers per Depot
Don’t bother telling me that this is impossible because this is what’s
really happening; there are on average a hundred truck and a hundred
container movements per day per depot.
Depot.find(:all, :includes => [:trucks, :containers])
= 0.040000 + 1.482000 + 1.732000
Depot.find(:all, :select => “depots.id, depots.name,
trucks.plate_no”, :joins => “LEFT JOIN trucks ON trucks.depot_id =
depots.id”)
= 1.242000
Looks faster than :include, BUT, we haven’t included Containers yet,
so we’ll included it now to go with your 1-SQL-using-joins theme:
Depot.find(:all, :select => “depots.id, depots.name, trucks.plate_no,
containers.serial_no”, :joins => “LEFT JOIN trucks ON trucks.depot_id
= depots.id LEFT JOIN containers ON containers.depot_id = depots.id”)
= 20+ minutes and still going strong!
Now I would like to see Fernando P. make an efficient :select :join
for MULTIPLE has_many relationships (without relying on multiple
SQLs) which can generate the report below, given the dataset
conditions that I have given above.
Depot
- List of Trucks -
- List of Containers -
Depot
- List of Trucks -
- List of Containers -
…
My conclusion is :joins >> :include by a factor 5-10, and I would not
recommend any advice from the railsenvy.com as they claim that you can
abuse of :include. This is certainly not true and can make your app go
really slow.
Again, it depends on the scenario. You’re basing your conclusion on a
simplistic model with a has_many → belongs_to chain. The
circumstances greatly change when you’re dealing with multiple
has_many relations.
Have a nice day.