DEV Community

Cover image for Rails ActiveRecord count, size and length, map and pluck
Dario Chuquilla
Dario Chuquilla

Posted on

Rails ActiveRecord count, size and length, map and pluck

Here I want to share with you some best practices for daily query requirements to help you improve the server's memory usage. We’ll discuss when to use each method and how they can help optimize memory usage and database calls.

Count and Size and length

All of these are used to get the number of records retrieved by the query.

Count

It returns the number of records by performing a query to the database every time it is called. I think it is pretty useful in asynchronous executions to bet the latest count of queries.

users = User.all
# SELECT "users".* FROM "users"
users.count
# SELECT COUNT(*) FROM users
Enter fullscreen mode Exit fullscreen mode

Size

This is a bit smarter, it calls to count in the database when records are not loaded in memory yet.

users = User.all
# SELECT "users".* FROM "users"
users.size
# No query needed, returns the number of records in memory
User.all.size
# SELECT COUNT(*) FROM users
Enter fullscreen mode Exit fullscreen mode

Length

This always gets from memory, It’s similar to size method, but it always loads the records.

users = User.all
# SELECT "users".* FROM "users"
users.length
# No query needed, returns the number of records in memory
User.all.length
SELECT "users".* FROM "users"
Enter fullscreen mode Exit fullscreen mode

A small recap

You will see how size and length queries to database.

User.all.size
# SELECT COUNT(*) FROM users
# Performs COUNT and saves that number into memory

User.all.length
SELECT "users".* FROM "users"
# Performs a full scan query, load that result into memory, and then gets the length of that array.
Enter fullscreen mode Exit fullscreen mode

Map and Pluck

To get an array of certain fields of query results.

Map

This method performs over the array of results of query and it only works with one field at a time, for more fields, you can pass a bloq as an argument, but first, it will load all fields of all records in memory.

User.all.map(&:id)
# SELECT "users".* FROM "users"
# [1, 2, 3, ...]
Enter fullscreen mode Exit fullscreen mode

Pluck

This is a more efficient method than map, it performs a query with the specific field you want to get, so It consumes less memory and traffic with DB.

User.pluck(:id, :first_name)
# SELECT "users"."id", "users"."first_name" FROM "users"
# [[1, "name 001"], [2, "name 002"], [3, "name 003"], ...]
Enter fullscreen mode Exit fullscreen mode

Conclusion

All of these methods are useful for all our requirements, sometimes it's better to load all info in memory at the beginning of the whole process (in tables with a small number of records), and it is necessary to control what you get from DB mostly in tables with a huge number of records.

For counting I prefer to use size to not call DB every time I need the number of records in a simple request flow. For a small number of fields 'pluck' is your friend.

Remember, optimizing database calls and memory usage is crucial for maintaining a fast, responsive Rails application. Always consider the trade-offs when choosing which ActiveRecord method to use.

I hope this helps! Let me know if you need any further assistance.

Top comments (1)

Collapse
 
epigene profile image
Augusts Bautra • Edited

pluck is so fast because it sidesteps ActiveRecord object initialization, only doing a DB query and returning the values without wrapping them in a model object.
Sometimes, however, the model is needed, maybe we want to call a method on each instance. There find_each may come handy.