Mateus Nava

Mateus Nava

May 04, 2022

Insert multiple records into the database (Rails and PostgreSQL)

By Joey Huang (unsplash.com)
By Joey Huang (unsplash.com)
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:
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
end

The 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 :).