At times, we need to insert millions of rows in a table for bench-marking or any other task. Using ActiveRecord for this purpose can hell lot of time.

For that we will write something like:

(1..1000000).times { |x| User.create(name: "User #{x}", email: "user#{x}@foo.bar", password: "12345678") }

The above will turn out to be terribly slow, taking somewhere around 20 minutes of your time(depends on your machine).

We can do much better if we use native sql queries for this purpose, and run them via ActiveRecord

Something like:

insert_query = (1..1000000).map { |x| "('User #{x}', 'user#{x}@foo.bar', '12345678')"}.join(", "); nil  # append nil in the end so that the entire insert query is not returned.

ActiveRecord::Base.connection.execute("INSERT INTO users (name, email, password) values #{insert_query}")

Now, this approach will take at max a minute of your time, instead of 20 minutes or so.

The main problem here is that ActiveRecord will construct queries on the go in first approach, while in the second approach we are giving our database handler the raw query that it needs to execute.