简体   繁体   中英

Rails test db 10x faster than development db

I have some seed data that creates 1000 users on my development setup. Occasionally I reset my db during the development process using this command:

rake db:reset

It inserts my users at a rate of about 10 users/second. I thought this was slow but learned to live with it.

I recently ran db:reset in the test environment while debugging some rspec tests using this command:

rake db:reset RAILS_ENV=test

It inserted users at approximately 100 users/second ! I can reproduce it and alternate between environments and the dev environment is slow while the test environment is fast.

It is using the exact same mysql setup in database.yml :

Development

development:
  adapter: mysql2
  encoding: utf8
  database: mydb
  username: mydb
  password: password
  host: 127.0.0.1
  port: 3306

Test

development:
  adapter: mysql2
  encoding: utf8
  database: mydb_test
  username: mydb_test
  password: password
  host: 127.0.0.1
  port: 3306

This is how I seed the users (same for both environments):

ActiveRecord::Base.transaction do
  1000.times do |i|
      User.create :first_name => Faker::Name.first_name, :last_name => Faker::Name.last_name, :email => Faker::Internet.email, :username => Faker::Internet.user_name, :password => '123456'
  end
end

Does anyone know what rails is doing to make the test env so fast? I'd like to implement these settings in the dev environment and speed up my seeding process by 10x.

I'd like to implement these settings in the dev environment and speed up my seeding process by 10x.

Bottom line is if you want to insert too many data instantly, you shouldn't consider using rails method. I suffered it.Rails attach too many callbacks like before_update, after_create etc . I have insert 500K data everydata. We have used raw sql to speed up the process. We did something like this

ActiveRecord::Base.transaction do
  inserts = []
  TIMES.times do
   inserts.push "(3.0, '2009-01-23 20:21:13', 2, 1)"
 end
 sql = "INSERT INTO user_node_scores (`score`, `updated_at`, `node_id`, `user_id`) VALUES #{inserts.join(", ")}"
 User.connection.execute  s
end

If you are using Devise, it could be caused by password stretching. In config/initializers/devise.rb :

# Limiting the stretches to just one in testing will increase the performance of
# your test suite dramatically. However, it is STRONGLY RECOMMENDED to not use
# a value less than 10 in other environments.
config.stretches = Rails.env.test? ? 1 : 10

That seems like difference between development and test envirionments you are looking for. Try playing with this line

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM