Know count, size, and length to save on SQL queries in Ruby on Rails
It’s important to know the differences between these three methods to ensure you’re triggering the fewest or most optimized SQL queries possible.
The count
method always triggers a SELECT count(*) FROM table
query.
The length
method ensures that the relationship has been loaded to count in memory.
The size
method adapts to the loading of the relationship. Either it triggers a query if it hasn't been loaded, or it counts in memory if it has already been loaded.
Here's a summary table:
Records Loaded | Record Not Loaded | |
---|---|---|
count |
SELECT count(*) FROM table |
SELECT count(*) FROM table |
size |
Count in memory | SELECT count(*) FROM table |
length |
Count in memory | SELECT * FROM table |
When counting and enumerating, it’s important to call size after the relationship has been loaded. In all cases, the aim is to trigger a single request.
# Bad 2 queries instead of 1
users = User.all
users.size # SELECT count(*) FROM "users"
users.each {} # SELECT "users".* FROM "users"
# Good
users = User.all
users.length # SELECT "users".* FROM "users"
users.each { } # No queries
# Good
users = User.all
users.each { } # SELECT "users".* FROM "users"
users.size # No queries
# Good
users = User.all.load # SELECT "users".* FROM "users"
users.size # No queries
users.each { } # No queries
# Bad 2 queries instead of 1
users = User.all
users.each { } # SELECT "users".* FROM "users"
users.count # SELECT COUNT(*) FROM "users"
All rights reserved