From 9e68653949c090ed6629f3edb20a59ef0bbfde03 Mon Sep 17 00:00:00 2001 From: Taloth Saldono Date: Fri, 10 May 2019 23:08:31 +0200 Subject: [PATCH] Fixed: Slow db migration when upgrading from v2 to v3 with a large collection --- ...e_to_episodeFiles_history_and_blacklist.cs | 117 ++++++++++-------- 1 file changed, 65 insertions(+), 52 deletions(-) diff --git a/src/NzbDrone.Core/Datastore/Migration/102_add_language_to_episodeFiles_history_and_blacklist.cs b/src/NzbDrone.Core/Datastore/Migration/102_add_language_to_episodeFiles_history_and_blacklist.cs index 39f46e333..59320f805 100644 --- a/src/NzbDrone.Core/Datastore/Migration/102_add_language_to_episodeFiles_history_and_blacklist.cs +++ b/src/NzbDrone.Core/Datastore/Migration/102_add_language_to_episodeFiles_history_and_blacklist.cs @@ -1,9 +1,12 @@ -using System.Data; +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; using FluentMigrator; +using NzbDrone.Common.Extensions; using NzbDrone.Core.Datastore.Migration.Framework; using NzbDrone.Core.Datastore.Converters; using NzbDrone.Core.Languages; -using System; namespace NzbDrone.Core.Datastore.Migration { @@ -28,6 +31,31 @@ private void UpdateLanguage(IDbConnection conn, IDbTransaction tran) { var LanguageConverter = new EmbeddedDocumentConverter(new LanguageIntConverter()); + var profileLanguages = new Dictionary(); + using (IDbCommand getProfileCmd = conn.CreateCommand()) + { + getProfileCmd.Transaction = tran; + getProfileCmd.CommandText = "SELECT Id, Language FROM Profiles"; + + IDataReader profilesReader = getProfileCmd.ExecuteReader(); + while (profilesReader.Read()) + { + var profileId = profilesReader.GetInt32(0); + var episodeLanguage = Language.English.Id; + try + { + episodeLanguage = profilesReader.GetInt32(1); + } + catch (InvalidCastException e) + { + _logger.Debug("Language field not found in Profiles, using English as default." + e.Message); + } + + profileLanguages[profileId] = episodeLanguage; + } + } + + var seriesLanguages = new Dictionary(); using (IDbCommand getSeriesCmd = conn.CreateCommand()) { getSeriesCmd.Transaction = tran; @@ -39,59 +67,44 @@ private void UpdateLanguage(IDbConnection conn, IDbTransaction tran) var seriesId = seriesReader.GetInt32(0); var seriesProfileId = seriesReader.GetInt32(1); - using (IDbCommand getProfileCmd = conn.CreateCommand()) - { - getProfileCmd.Transaction = tran; - getProfileCmd.CommandText = "SELECT Language FROM Profiles WHERE Id = ?"; - getProfileCmd.AddParameter(seriesProfileId); - IDataReader profilesReader = getProfileCmd.ExecuteReader(); - while (profilesReader.Read()) - { - var episodeLanguage = Language.English.Id; - try - { - episodeLanguage = profilesReader.GetInt32(0); - } catch (InvalidCastException e) - { - _logger.Debug("Language field not found in Profiles, using English as default." + e.Message); - } - - var validJson = LanguageConverter.ToDB(Language.FindById(episodeLanguage)); - - using (IDbCommand updateEpisodeFilesCmd = conn.CreateCommand()) - { - updateEpisodeFilesCmd.Transaction = tran; - updateEpisodeFilesCmd.CommandText = "UPDATE EpisodeFiles SET Language = ? WHERE SeriesId = ?"; - updateEpisodeFilesCmd.AddParameter(validJson); - updateEpisodeFilesCmd.AddParameter(seriesId); - - updateEpisodeFilesCmd.ExecuteNonQuery(); - } - - using (IDbCommand updateHistoryCmd = conn.CreateCommand()) - { - updateHistoryCmd.Transaction = tran; - updateHistoryCmd.CommandText = "UPDATE History SET Language = ? WHERE SeriesId = ?"; - updateHistoryCmd.AddParameter(validJson); - updateHistoryCmd.AddParameter(seriesId); - - updateHistoryCmd.ExecuteNonQuery(); - } - - using (IDbCommand updateBlacklistCmd = conn.CreateCommand()) - { - updateBlacklistCmd.Transaction = tran; - updateBlacklistCmd.CommandText = "UPDATE Blacklist SET Language = ? WHERE SeriesId = ?"; - updateBlacklistCmd.AddParameter(validJson); - updateBlacklistCmd.AddParameter(seriesId); - - updateBlacklistCmd.ExecuteNonQuery(); - } - } - } + seriesLanguages[seriesId] = profileLanguages.GetValueOrDefault(seriesProfileId, Language.English.Id); } } } + + foreach (var group in seriesLanguages.GroupBy(v => v.Value, v => v.Key)) + { + var languageJson = LanguageConverter.ToDB(Language.FindById(group.Key)); + + var seriesIds = group.Select(v => v.ToString()).Join(","); + + using (IDbCommand updateEpisodeFilesCmd = conn.CreateCommand()) + { + updateEpisodeFilesCmd.Transaction = tran; + updateEpisodeFilesCmd.CommandText = $"UPDATE EpisodeFiles SET Language = ? WHERE SeriesId IN ({seriesIds})"; + updateEpisodeFilesCmd.AddParameter(languageJson); + + updateEpisodeFilesCmd.ExecuteNonQuery(); + } + + using (IDbCommand updateHistoryCmd = conn.CreateCommand()) + { + updateHistoryCmd.Transaction = tran; + updateHistoryCmd.CommandText = $"UPDATE History SET Language = ? WHERE SeriesId IN ({seriesIds})"; + updateHistoryCmd.AddParameter(languageJson); + + updateHistoryCmd.ExecuteNonQuery(); + } + + using (IDbCommand updateBlacklistCmd = conn.CreateCommand()) + { + updateBlacklistCmd.Transaction = tran; + updateBlacklistCmd.CommandText = $"UPDATE Blacklist SET Language = ? WHERE SeriesId IN ({seriesIds})"; + updateBlacklistCmd.AddParameter(languageJson); + + updateBlacklistCmd.ExecuteNonQuery(); + } + } } } }