diff options
-rw-r--r-- | activerecord/CHANGELOG.md | 5 | ||||
-rw-r--r-- | activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb | 18 |
2 files changed, 13 insertions, 10 deletions
diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md index f3dc26ddb3..b59c9b4635 100644 --- a/activerecord/CHANGELOG.md +++ b/activerecord/CHANGELOG.md @@ -1,3 +1,8 @@ +* Improve schema_migrations insertion performance by inserting all versions + in one INSERT SQL. + + *Akira Matsuda*, *Naoto Koshikawa* + * Using `references` or `belongs_to` in migrations will always add index for the referenced column by default, without adding `index: true` option to generated migration file. Users can opt out of this by passing diff --git a/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb b/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb index 70868ebd03..002f2ea8ce 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb @@ -957,9 +957,9 @@ module ActiveRecord def dump_schema_information #:nodoc: sm_table = ActiveRecord::Migrator.schema_migrations_table_name - ActiveRecord::SchemaMigration.order('version').map { |sm| - "INSERT INTO #{sm_table} (version) VALUES ('#{sm.version}');" - }.join "\n\n" + sql = "INSERT INTO #{sm_table} (version) VALUES " + sql << ActiveRecord::SchemaMigration.order('version').pluck(:version).map {|v| "('#{v}')" }.join(', ') + sql << ";\n\n" end # Should not be called normally, but this operation is non-destructive. @@ -987,14 +987,12 @@ module ActiveRecord execute "INSERT INTO #{sm_table} (version) VALUES ('#{version}')" end - inserted = Set.new - (versions - migrated).each do |v| - if inserted.include?(v) - raise "Duplicate migration #{v}. Please renumber your migrations to resolve the conflict." - elsif v < version - execute "INSERT INTO #{sm_table} (version) VALUES ('#{v}')" - inserted << v + inserting = (versions - migrated).select {|v| v < version} + if inserting.any? + if (duplicate = inserting.detect {|v| inserting.count(v) > 1}) + raise "Duplicate migration #{duplicate}. Please renumber your migrations to resolve the conflict." end + execute "INSERT INTO #{sm_table} (version) VALUES #{inserting.map {|v| '(#{v})'}.join(', ') }" end end |