May 04, 2022
Insert multiple records into the database (Rails and PostgreSQL)
To complete the feature that I'm developing, I have to insert a large list of items into the database, it's simple but I would like to insert it in the shortest possible time. To do this I have enumerated two ways and I will compare the time for operations to decide which is the best.
To measure the time I'm using the very useful native ruby tool: Benchmark
To prepare the environment I'm just using this recipe:
To measure the time I'm using the very useful native ruby tool: Benchmark
To prepare the environment I'm just using this recipe:
rails g model person name:string rails db:migrate
* You can check out some tips for trying new things in Rails in the post - https://www.mateusnava.com/posts/a-simple-technique-for-trying-out-new-things-in-rails
First Experiment
The first option is the "classic", I open a transaction with the database and inside it, I insert records, one by one.
Person.transaction do
5_000.times do
Person.create!(name: Faker::Name.name)
end
endThe result:
{
"real": 5.51667699997779
} Second Experiment
For the second experiment, I'm using Active Record's insert_all method.
items = 5_000.times.map do
{
name: Faker::Name.name
}
end
Person.insert_all(items)The result:
{
"real": 1.5328290000325069
} 🙀😱 This is much faster than the first option. 💜 insert_all
There are two important aspects to speeding up this operation:
- PostgreSQL multiline insert feature - single SQL INSERT statement (https://www.postgresql.org/docs/current/dml-insert.html)
- Rails does not instantiate any model (no trigger Active Record callbacks or validations)
Thanks :).