1
0
Fork 0
mirror of https://github.com/rails/rails.git synced 2022-11-09 12:12:34 -05:00

INSERT INTO schema_migrations in 1 SQL

We found that inserting all 600 schema_migrations for our mid-sized app takes about a minute on a cloud based CI environment.

I assume that the original code did not use multi-row-insert because SQLite3 was not supporting the syntax back then,
but it's been supported since 3.7.11: http://www.sqlite.org/releaselog/3_7_11.html
This commit is contained in:
Akira Matsuda & Naoto Koshikawa 2016-01-27 17:44:27 +09:00 committed by Akira Matsuda
parent 3844854af1
commit 42dd2336b3
2 changed files with 13 additions and 10 deletions

View file

@ -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

View file

@ -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