diff --git a/lib/ci/migrate/tags.rb b/lib/ci/migrate/tags.rb
index 125a535e9a93416525584768ee22b43a57bb54a3..2bbd253f8deed34a8f6b60c0601e42eb1f7e45d8 100644
--- a/lib/ci/migrate/tags.rb
+++ b/lib/ci/migrate/tags.rb
@@ -4,45 +4,37 @@ module Ci
   module Migrate
     class Tags
       def restore
-        puts 'Migrating tags for Runners... '
-        list_objects('Runner').each do |id|
-          putc '.'
-          runner = Ci::Runner.find_by_id(id)
-          if runner
-            tags = list_tags('Runner', id)
-            runner.update_attributes(tag_list: tags)
-          end
-        end
-        puts ''
+        ActiveRecord::Base.transaction do
+          puts 'Inserting tags...'
+          connection.execute(
+            'INSERT INTO tags (name) ' +
+              'SELECT ci_tags.name FROM ci_tags ' +
+              'WHERE (SELECT COUNT(*) FROM tags WHERE tags.name = ci_tags.name)=0'
+          )
+
+          puts 'Deleting old records'
+          connection.execute "DELETE FROM taggings WHERE context = 'tags' AND taggable_type LIKE 'Ci::%'"
+
+          puts 'Inserting tags...'
+          connection.execute(
+            'INSERT INTO taggings (taggable_type, taggable_id, tag_id, context) ' +
+              "SELECT CONCAT('Ci::', ci_taggings.taggable_type), ci_taggings.taggable_id, tags.id, 'tags' FROM ci_taggings " +
+              'JOIN ci_tags ON ci_tags.id = ci_taggings.tag_id ' +
+              'JOIN tags ON tags.name = ci_tags.name '
+          )
 
-        puts 'Migrating tags for Builds... '
-        list_objects('Build').each do |id|
-          putc '.'
-          build = Ci::Build.find_by_id(id)
-          if build
-            tags = list_tags('Build', id)
-            build.update_attributes(tag_list: tags)
-          end
+          puts 'Resetting counters... '
+          connection.execute(
+            'UPDATE tags SET ' +
+              'taggings_count = (SELECT COUNT(*) FROM taggings WHERE tags.id = taggings.tag_id)'
+          )
         end
-        puts ''
       end
 
       protected
 
-      def list_objects(type)
-        ids = ActiveRecord::Base.connection.select_all(
-          "select distinct taggable_id from ci_taggings where taggable_type = #{ActiveRecord::Base::sanitize(type)}"
-        )
-        ids.map { |id| id['taggable_id'] }
-      end
-
-      def list_tags(type, id)
-        tags = ActiveRecord::Base.connection.select_all(
-          'select ci_tags.name from ci_tags ' +
-            'join ci_taggings on ci_tags.id = ci_taggings.tag_id ' +
-            "where taggable_type = #{ActiveRecord::Base::sanitize(type)} and taggable_id = #{ActiveRecord::Base::sanitize(id)} and context = 'tags'"
-        )
-        tags.map { |tag| tag['name'] }
+      def connection
+        ActiveRecord::Base.connection
       end
     end
   end