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

  • 5
    いいね
  • 0
    コメント

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分近い差がでました。

この投稿は CircleCI Advent Calendar 201519日目の記事です。