Rails ActiveRecord count, size and length, map and pluck

dchuquilla

Dario Chuquilla

Posted on March 15, 2024

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.

💖 💪 🙅 🚩
dchuquilla
Dario Chuquilla

Posted on March 15, 2024

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related