1

The two Active Record queries: User.first.followers.count and User.first.followers.to_a.count evaluate to the following SQL queries respectively:

[4] pry(main)> User.first.followers.count
  User Load (0.2ms)  SELECT  "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT ?  [["LIMIT", 1]]
   (0.3ms)  SELECT COUNT(*) FROM "users" INNER JOIN "relationships" ON "users"."id" = "relationships"."follower_id" WHERE "relationships"."followed_id" = ?  [["followed_id", 1]]
=> 4
[5] pry(main)> User.first.followers.to_a.count
  User Load (0.1ms)  SELECT  "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT ?  [["LIMIT", 1]]
  User Load (0.1ms)  SELECT "users".* FROM "users" INNER JOIN "relationships" ON "users"."id" = "relationships"."follower_id" WHERE "relationships"."followed_id" = ?  [["followed_id", 1]]
=> 4

How are they conceptually different?

This question came up in an exercise question at the end of section 14.1 in The Rails Tutorial

He gives the following hint:

Hint: Suppose that the user had a million followers.

mbigras
  • 7,664
  • 11
  • 50
  • 111
  • Possible duplicate of [Count(\*) vs Count(1)](http://stackoverflow.com/questions/1221559/count-vs-count1) – Shakeer Mirza Dec 05 '16 at 06:29
  • 1
    I don't think you can call this a significant difference. We are talking about a single data-point with sub-millisecond response time. Note that the first query is identical in both cases, but takes 0.2ms vs 0.1ms in your two samples. You need to benchmark more extensively. – Thilo Dec 05 '16 at 07:17
  • It's possible that you measured the cache effect. You need to do more repetitions, and use a timer with a better resolution. – CL. Dec 05 '16 at 08:18
  • Thank for the comments, I see that the time may be misleading. I know there is some sort of difference between those two commands because the author is saying there is. But I'm not sure what the conceptual difference is between the two so I'm not sure what to search for. I know In both cases we're getting the count of a collection of items but in the second instance it's an array. On the database level this has some sort of effect, b/c the sql commands are different, but I'm not sure what the difference is in words. – mbigras Dec 05 '16 at 08:23
  • The first version counts in the database, the second version selects all rows and counts in Ruby. – Thilo Dec 05 '16 at 11:17
  • @Thilo in the second version are all the rows pulled out of the database? In the first version do they stay? – mbigras Dec 05 '16 at 17:12
  • 1
    `select count` will return just the number of rows. `select *` will return the rows (with all their columns) themselves. – Thilo Dec 05 '16 at 23:45

0 Answers0