Hello everyone! I’ve a question that I hope someone in here would be able to answer. Today I was writing a simple test for a method that takes the last “n” (where n is an integer) users that signed up on my web app.
I know it’s a simple method, but then I started to think about the optimal way to query the DB, and I tried different options. The first thing I did was create 1000 users through a simple:
1000.times {Factory(:student)}
The difference between the first and the last records is about 2 minutes.
first created_at: 2010-12-15 20:35:41
last created_at: 2010-12-15 20:37:51
And this is what I’ve got on the console when using ActiveRecord::Base.uncached:
User.order(“created_at DESC”).limit(5).reverse
User Load (7.4ms) SELECT “users”.* FROM “users” ORDER BY created_at DESC LIMIT 5
User.order(“created_at ASC”).last(5)
User Load (1179.1ms) SELECT “users”.* FROM “users” ORDER BY created_at ASC
User.last(5) # I didn’t even know I could add a parameter to last
User Load (1171.2ms) SELECT “users”.* FROM “users”
User.all.last(5)
User Load (1177.3ms) SELECT “users”.* FROM “users”
Well, there’s obviously a huge performance impact between querying the DB with the first one and the rest. There’re some things I would love to understand.
-
If the users are created in order, this means the last user is the last that signed up. This means that the first query would have had to order all the 1000 users by date, then take only 5 and then reverse the array right??? So, why is it so fast???
-
The second query, in this case would not have to order the users, as by default they are all ordered right? So, it would only have to take the last 5 elements of the array. But why is it slower than the first one?
-
The third and fourth queries, I guess load all the users in memory and then return only the last 5.
Any information about this would be really helpful. Thanks.