Edited at
CircleCIDay 19

CircleCIでrake db:structure:loadが遅い場合のでschema_migrationsをBULK INSERTした

More than 1 year has passed since last update.

migrationファイルの中に特殊な処理があるときなどは、db/schema.rbではdbのテーブル構成を忠実に再現出来ないケースが有り、その場合は生のSQLを使うdb/structure.sqlをdumpする方法があります。

こんな感じで設定出来ます。


config/application.rb

module YourApp

class Application < Rails::Application
config.active_record.schema_format = :sql
end
end

このときrake db:schema:loadからrake db:structure:loadに変えたところ、CircleCIにおいて、処理速度が遅くなってしまったので調べていたところ、

bundle exec rake db:structure:dumpの最後のschema_migrationsテーブルの中身をdumpする処理BULK INSERTではなかったので、ちょろっと調整してみました。


config/initializers/extensions/active_record.rb

module ActiveRecord

module ConnectionAdapters
module SchemaStatements
# CircleCIでのINSERTがとにかく遅いのでBulk Insertでschema_migrationsを出力する
def dump_schema_information
sm_table = ActiveRecord::Migrator.schema_migrations_table_name

sql = String.new
sql << "INSERT INTO #{sm_table} (version) VALUES"
sql << ActiveRecord::SchemaMigration.order('version').map { |sm|
"('#{sm.version}')"
}.join(",")
sql << ";\n\n"
end
end
end
end


テーブル数200強、migration数が600弱という環境で、ローカルのmacだと以下ぐらいの差です。


  • MacBook Pro (Retina, 15-inch, Mid 2014)

  • プロセッサ: 2.2 GHz Intel Core i7

  • メモリ: 16 GB 1600 MHz DDR3


before

time bundle exec rake db:structure:load  5.60s user 3.71s system 63% cpu 14.592 total


After

time bundle exec rake db:structure:load  4.46s user 2.05s system 65% cpu 9.973 total

CircleCIだと1分近い差がでました。